OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 #if V8_TARGET_ARCH_PPC64 | 70 #if V8_TARGET_ARCH_PPC64 |
71 if (cpu.part() == base::CPU::PPC_POWER8) { | 71 if (cpu.part() == base::CPU::PPC_POWER8) { |
72 supported_ |= (1u << FPR_GPR_MOV); | 72 supported_ |= (1u << FPR_GPR_MOV); |
73 } | 73 } |
74 #endif | 74 #endif |
75 if (cpu.part() == base::CPU::PPC_POWER6 || | 75 if (cpu.part() == base::CPU::PPC_POWER6 || |
76 cpu.part() == base::CPU::PPC_POWER7 || | 76 cpu.part() == base::CPU::PPC_POWER7 || |
77 cpu.part() == base::CPU::PPC_POWER8) { | 77 cpu.part() == base::CPU::PPC_POWER8) { |
78 supported_ |= (1u << LWSYNC); | 78 supported_ |= (1u << LWSYNC); |
79 } | 79 } |
| 80 if (cpu.part() == base::CPU::PPC_POWER7 || |
| 81 cpu.part() == base::CPU::PPC_POWER8) { |
| 82 supported_ |= (1u << ISELECT); |
| 83 } |
80 #if V8_OS_LINUX | 84 #if V8_OS_LINUX |
81 if (!(cpu.part() == base::CPU::PPC_G5 || cpu.part() == base::CPU::PPC_G4)) { | 85 if (!(cpu.part() == base::CPU::PPC_G5 || cpu.part() == base::CPU::PPC_G4)) { |
82 // Assume support | 86 // Assume support |
83 supported_ |= (1u << FPU); | 87 supported_ |= (1u << FPU); |
84 } | 88 } |
85 #elif V8_OS_AIX | 89 #elif V8_OS_AIX |
86 // Assume support FP support and default cache line size | 90 // Assume support FP support and default cache line size |
87 supported_ |= (1u << FPU); | 91 supported_ |= (1u << FPU); |
88 #endif | 92 #endif |
89 #else // Simulator | 93 #else // Simulator |
90 supported_ |= (1u << FPU); | 94 supported_ |= (1u << FPU); |
91 supported_ |= (1u << LWSYNC); | 95 supported_ |= (1u << LWSYNC); |
| 96 supported_ |= (1u << ISELECT); |
92 #if V8_TARGET_ARCH_PPC64 | 97 #if V8_TARGET_ARCH_PPC64 |
93 supported_ |= (1u << FPR_GPR_MOV); | 98 supported_ |= (1u << FPR_GPR_MOV); |
94 #endif | 99 #endif |
95 #endif | 100 #endif |
96 } | 101 } |
97 | 102 |
98 | 103 |
99 void CpuFeatures::PrintTarget() { | 104 void CpuFeatures::PrintTarget() { |
100 const char* ppc_arch = NULL; | 105 const char* ppc_arch = NULL; |
101 | 106 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 MemOperand::MemOperand(Register ra, Register rb) { | 215 MemOperand::MemOperand(Register ra, Register rb) { |
211 ra_ = ra; | 216 ra_ = ra; |
212 rb_ = rb; | 217 rb_ = rb; |
213 offset_ = 0; | 218 offset_ = 0; |
214 } | 219 } |
215 | 220 |
216 | 221 |
217 // ----------------------------------------------------------------------------- | 222 // ----------------------------------------------------------------------------- |
218 // Specific instructions, constants, and masks. | 223 // Specific instructions, constants, and masks. |
219 | 224 |
220 // Spare buffer. | |
221 static const int kMinimalBufferSize = 4 * KB; | |
222 | |
223 | 225 |
224 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) | 226 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) |
225 : AssemblerBase(isolate, buffer, buffer_size), | 227 : AssemblerBase(isolate, buffer, buffer_size), |
226 recorded_ast_id_(TypeFeedbackId::None()), | 228 recorded_ast_id_(TypeFeedbackId::None()), |
227 #if V8_OOL_CONSTANT_POOL | 229 #if V8_OOL_CONSTANT_POOL |
228 constant_pool_builder_(), | 230 constant_pool_builder_(), |
229 #endif | 231 #endif |
230 positions_recorder_(this) { | 232 positions_recorder_(this) { |
231 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); | 233 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); |
232 | 234 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 } else if ((instr & ~kImm26Mask) == 0) { | 417 } else if ((instr & ~kImm26Mask) == 0) { |
416 // Emitted link to a label, not part of a branch (regexp PushBacktrack). | 418 // Emitted link to a label, not part of a branch (regexp PushBacktrack). |
417 if (instr == 0) { | 419 if (instr == 0) { |
418 return kEndOfChain; | 420 return kEndOfChain; |
419 } else { | 421 } else { |
420 int32_t imm26 = SIGN_EXT_IMM26(instr); | 422 int32_t imm26 = SIGN_EXT_IMM26(instr); |
421 return (imm26 + pos); | 423 return (imm26 + pos); |
422 } | 424 } |
423 } | 425 } |
424 | 426 |
425 PPCPORT_UNIMPLEMENTED(); | |
426 DCHECK(false); | 427 DCHECK(false); |
427 return -1; | 428 return -1; |
428 } | 429 } |
429 | 430 |
430 | 431 |
431 void Assembler::target_at_put(int pos, int target_pos) { | 432 void Assembler::target_at_put(int pos, int target_pos) { |
432 Instr instr = instr_at(pos); | 433 Instr instr = instr_at(pos); |
433 int opcode = instr & kOpcodeMask; | 434 int opcode = instr & kOpcodeMask; |
434 | 435 |
435 // check which type of branch this is 16 or 26 bit offset | 436 // check which type of branch this is 16 or 26 bit offset |
436 if (BX == opcode) { | 437 if (BX == opcode) { |
437 int imm26 = target_pos - pos; | 438 int imm26 = target_pos - pos; |
438 DCHECK((imm26 & (kAAMask | kLKMask)) == 0); | 439 DCHECK(is_int26(imm26) && (imm26 & (kAAMask | kLKMask)) == 0); |
439 instr &= ((~kImm26Mask) | kAAMask | kLKMask); | 440 if (imm26 == kInstrSize && !(instr & kLKMask)) { |
440 DCHECK(is_int26(imm26)); | 441 // Branch to next instr without link. |
441 instr_at_put(pos, instr | (imm26 & kImm26Mask)); | 442 instr = ORI; // nop: ori, 0,0,0 |
| 443 } else { |
| 444 instr &= ((~kImm26Mask) | kAAMask | kLKMask); |
| 445 instr |= (imm26 & kImm26Mask); |
| 446 } |
| 447 instr_at_put(pos, instr); |
442 return; | 448 return; |
443 } else if (BCX == opcode) { | 449 } else if (BCX == opcode) { |
444 int imm16 = target_pos - pos; | 450 int imm16 = target_pos - pos; |
445 DCHECK((imm16 & (kAAMask | kLKMask)) == 0); | 451 DCHECK(is_int16(imm16) && (imm16 & (kAAMask | kLKMask)) == 0); |
446 instr &= ((~kImm16Mask) | kAAMask | kLKMask); | 452 if (imm16 == kInstrSize && !(instr & kLKMask)) { |
447 DCHECK(is_int16(imm16)); | 453 // Branch to next instr without link. |
448 instr_at_put(pos, instr | (imm16 & kImm16Mask)); | 454 instr = ORI; // nop: ori, 0,0,0 |
| 455 } else { |
| 456 instr &= ((~kImm16Mask) | kAAMask | kLKMask); |
| 457 instr |= (imm16 & kImm16Mask); |
| 458 } |
| 459 instr_at_put(pos, instr); |
449 return; | 460 return; |
450 } else if ((instr & ~kImm26Mask) == 0) { | 461 } else if ((instr & ~kImm26Mask) == 0) { |
451 DCHECK(target_pos == kEndOfChain || target_pos >= 0); | 462 DCHECK(target_pos == kEndOfChain || target_pos >= 0); |
452 // Emitted link to a label, not part of a branch (regexp PushBacktrack). | 463 // Emitted link to a label, not part of a branch (regexp PushBacktrack). |
453 // Load the position of the label relative to the generated code object | 464 // Load the position of the label relative to the generated code object |
454 // pointer in a register. | 465 // pointer in a register. |
455 | 466 |
456 Register dst = r3; // we assume r3 for now | 467 Register dst = r3; // we assume r3 for now |
457 DCHECK(IsNop(instr_at(pos + kInstrSize))); | 468 DCHECK(IsNop(instr_at(pos + kInstrSize))); |
458 uint32_t target = target_pos + (Code::kHeaderSize - kHeapObjectTag); | 469 uint32_t target = target_pos + (Code::kHeaderSize - kHeapObjectTag); |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 | 862 |
852 | 863 |
853 // Multiply low word | 864 // Multiply low word |
854 void Assembler::mullw(Register dst, Register src1, Register src2, OEBit o, | 865 void Assembler::mullw(Register dst, Register src1, Register src2, OEBit o, |
855 RCBit r) { | 866 RCBit r) { |
856 xo_form(EXT2 | MULLW, dst, src1, src2, o, r); | 867 xo_form(EXT2 | MULLW, dst, src1, src2, o, r); |
857 } | 868 } |
858 | 869 |
859 | 870 |
860 // Multiply hi word | 871 // Multiply hi word |
861 void Assembler::mulhw(Register dst, Register src1, Register src2, OEBit o, | 872 void Assembler::mulhw(Register dst, Register src1, Register src2, RCBit r) { |
862 RCBit r) { | 873 xo_form(EXT2 | MULHWX, dst, src1, src2, LeaveOE, r); |
863 xo_form(EXT2 | MULHWX, dst, src1, src2, o, r); | |
864 } | 874 } |
865 | 875 |
866 | 876 |
| 877 // Multiply hi word unsigned |
| 878 void Assembler::mulhwu(Register dst, Register src1, Register src2, RCBit r) { |
| 879 xo_form(EXT2 | MULHWUX, dst, src1, src2, LeaveOE, r); |
| 880 } |
| 881 |
| 882 |
867 // Divide word | 883 // Divide word |
868 void Assembler::divw(Register dst, Register src1, Register src2, OEBit o, | 884 void Assembler::divw(Register dst, Register src1, Register src2, OEBit o, |
869 RCBit r) { | 885 RCBit r) { |
870 xo_form(EXT2 | DIVW, dst, src1, src2, o, r); | 886 xo_form(EXT2 | DIVW, dst, src1, src2, o, r); |
871 } | 887 } |
872 | 888 |
873 | 889 |
| 890 // Divide word unsigned |
| 891 void Assembler::divwu(Register dst, Register src1, Register src2, OEBit o, |
| 892 RCBit r) { |
| 893 xo_form(EXT2 | DIVWU, dst, src1, src2, o, r); |
| 894 } |
| 895 |
| 896 |
874 void Assembler::addi(Register dst, Register src, const Operand& imm) { | 897 void Assembler::addi(Register dst, Register src, const Operand& imm) { |
875 DCHECK(!src.is(r0)); // use li instead to show intent | 898 DCHECK(!src.is(r0)); // use li instead to show intent |
876 d_form(ADDI, dst, src, imm.imm_, true); | 899 d_form(ADDI, dst, src, imm.imm_, true); |
877 } | 900 } |
878 | 901 |
879 | 902 |
880 void Assembler::addis(Register dst, Register src, const Operand& imm) { | 903 void Assembler::addis(Register dst, Register src, const Operand& imm) { |
881 DCHECK(!src.is(r0)); // use lis instead to show intent | 904 DCHECK(!src.is(r0)); // use lis instead to show intent |
882 d_form(ADDIS, dst, src, imm.imm_, true); | 905 d_form(ADDIS, dst, src, imm.imm_, true); |
883 } | 906 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 void Assembler::oris(Register dst, Register src, const Operand& imm) { | 939 void Assembler::oris(Register dst, Register src, const Operand& imm) { |
917 d_form(ORIS, src, dst, imm.imm_, false); | 940 d_form(ORIS, src, dst, imm.imm_, false); |
918 } | 941 } |
919 | 942 |
920 | 943 |
921 void Assembler::orx(Register dst, Register src1, Register src2, RCBit rc) { | 944 void Assembler::orx(Register dst, Register src1, Register src2, RCBit rc) { |
922 x_form(EXT2 | ORX, dst, src1, src2, rc); | 945 x_form(EXT2 | ORX, dst, src1, src2, rc); |
923 } | 946 } |
924 | 947 |
925 | 948 |
| 949 void Assembler::orc(Register dst, Register src1, Register src2, RCBit rc) { |
| 950 x_form(EXT2 | ORC, dst, src1, src2, rc); |
| 951 } |
| 952 |
| 953 |
926 void Assembler::cmpi(Register src1, const Operand& src2, CRegister cr) { | 954 void Assembler::cmpi(Register src1, const Operand& src2, CRegister cr) { |
927 intptr_t imm16 = src2.imm_; | 955 intptr_t imm16 = src2.imm_; |
928 #if V8_TARGET_ARCH_PPC64 | 956 #if V8_TARGET_ARCH_PPC64 |
929 int L = 1; | 957 int L = 1; |
930 #else | 958 #else |
931 int L = 0; | 959 int L = 0; |
932 #endif | 960 #endif |
933 DCHECK(is_int16(imm16)); | 961 DCHECK(is_int16(imm16)); |
934 DCHECK(cr.code() >= 0 && cr.code() <= 7); | 962 DCHECK(cr.code() >= 0 && cr.code() <= 7); |
935 imm16 &= kImm16Mask; | 963 imm16 &= kImm16Mask; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 | 1032 |
1005 | 1033 |
1006 void Assembler::cmplw(Register src1, Register src2, CRegister cr) { | 1034 void Assembler::cmplw(Register src1, Register src2, CRegister cr) { |
1007 int L = 0; | 1035 int L = 0; |
1008 DCHECK(cr.code() >= 0 && cr.code() <= 7); | 1036 DCHECK(cr.code() >= 0 && cr.code() <= 7); |
1009 emit(EXT2 | CMPL | cr.code() * B23 | L * B21 | src1.code() * B16 | | 1037 emit(EXT2 | CMPL | cr.code() * B23 | L * B21 | src1.code() * B16 | |
1010 src2.code() * B11); | 1038 src2.code() * B11); |
1011 } | 1039 } |
1012 | 1040 |
1013 | 1041 |
| 1042 void Assembler::isel(Register rt, Register ra, Register rb, int cb) { |
| 1043 emit(EXT2 | ISEL | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 | |
| 1044 cb * B6); |
| 1045 } |
| 1046 |
| 1047 |
1014 // Pseudo op - load immediate | 1048 // Pseudo op - load immediate |
1015 void Assembler::li(Register dst, const Operand& imm) { | 1049 void Assembler::li(Register dst, const Operand& imm) { |
1016 d_form(ADDI, dst, r0, imm.imm_, true); | 1050 d_form(ADDI, dst, r0, imm.imm_, true); |
1017 } | 1051 } |
1018 | 1052 |
1019 | 1053 |
1020 void Assembler::lis(Register dst, const Operand& imm) { | 1054 void Assembler::lis(Register dst, const Operand& imm) { |
1021 d_form(ADDIS, dst, r0, imm.imm_, true); | 1055 d_form(ADDIS, dst, r0, imm.imm_, true); |
1022 } | 1056 } |
1023 | 1057 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 | 1104 |
1071 void Assembler::lhzux(Register rt, const MemOperand& src) { | 1105 void Assembler::lhzux(Register rt, const MemOperand& src) { |
1072 Register ra = src.ra(); | 1106 Register ra = src.ra(); |
1073 Register rb = src.rb(); | 1107 Register rb = src.rb(); |
1074 DCHECK(!ra.is(r0)); | 1108 DCHECK(!ra.is(r0)); |
1075 emit(EXT2 | LHZUX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 | | 1109 emit(EXT2 | LHZUX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 | |
1076 LeaveRC); | 1110 LeaveRC); |
1077 } | 1111 } |
1078 | 1112 |
1079 | 1113 |
| 1114 void Assembler::lhax(Register rt, const MemOperand& src) { |
| 1115 Register ra = src.ra(); |
| 1116 Register rb = src.rb(); |
| 1117 DCHECK(!ra.is(r0)); |
| 1118 emit(EXT2 | LHAX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11); |
| 1119 } |
| 1120 |
| 1121 |
1080 void Assembler::lwz(Register dst, const MemOperand& src) { | 1122 void Assembler::lwz(Register dst, const MemOperand& src) { |
1081 DCHECK(!src.ra_.is(r0)); | 1123 DCHECK(!src.ra_.is(r0)); |
1082 d_form(LWZ, dst, src.ra(), src.offset(), true); | 1124 d_form(LWZ, dst, src.ra(), src.offset(), true); |
1083 } | 1125 } |
1084 | 1126 |
1085 | 1127 |
1086 void Assembler::lwzu(Register dst, const MemOperand& src) { | 1128 void Assembler::lwzu(Register dst, const MemOperand& src) { |
1087 DCHECK(!src.ra_.is(r0)); | 1129 DCHECK(!src.ra_.is(r0)); |
1088 d_form(LWZU, dst, src.ra(), src.offset(), true); | 1130 d_form(LWZU, dst, src.ra(), src.offset(), true); |
1089 } | 1131 } |
(...skipping 10 matching lines...) Expand all Loading... |
1100 | 1142 |
1101 void Assembler::lwzux(Register rt, const MemOperand& src) { | 1143 void Assembler::lwzux(Register rt, const MemOperand& src) { |
1102 Register ra = src.ra(); | 1144 Register ra = src.ra(); |
1103 Register rb = src.rb(); | 1145 Register rb = src.rb(); |
1104 DCHECK(!ra.is(r0)); | 1146 DCHECK(!ra.is(r0)); |
1105 emit(EXT2 | LWZUX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 | | 1147 emit(EXT2 | LWZUX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 | |
1106 LeaveRC); | 1148 LeaveRC); |
1107 } | 1149 } |
1108 | 1150 |
1109 | 1151 |
| 1152 void Assembler::lha(Register dst, const MemOperand& src) { |
| 1153 DCHECK(!src.ra_.is(r0)); |
| 1154 d_form(LHA, dst, src.ra(), src.offset(), true); |
| 1155 } |
| 1156 |
| 1157 |
1110 void Assembler::lwa(Register dst, const MemOperand& src) { | 1158 void Assembler::lwa(Register dst, const MemOperand& src) { |
1111 #if V8_TARGET_ARCH_PPC64 | 1159 #if V8_TARGET_ARCH_PPC64 |
1112 int offset = src.offset(); | 1160 int offset = src.offset(); |
1113 DCHECK(!src.ra_.is(r0)); | 1161 DCHECK(!src.ra_.is(r0)); |
1114 DCHECK(!(offset & 3) && is_int16(offset)); | 1162 DCHECK(!(offset & 3) && is_int16(offset)); |
1115 offset = kImm16Mask & offset; | 1163 offset = kImm16Mask & offset; |
1116 emit(LD | dst.code() * B21 | src.ra().code() * B16 | offset | 2); | 1164 emit(LD | dst.code() * B21 | src.ra().code() * B16 | offset | 2); |
1117 #else | 1165 #else |
1118 lwz(dst, src); | 1166 lwz(dst, src); |
1119 #endif | 1167 #endif |
1120 } | 1168 } |
1121 | 1169 |
1122 | 1170 |
| 1171 void Assembler::lwax(Register rt, const MemOperand& src) { |
| 1172 #if V8_TARGET_ARCH_PPC64 |
| 1173 Register ra = src.ra(); |
| 1174 Register rb = src.rb(); |
| 1175 DCHECK(!ra.is(r0)); |
| 1176 emit(EXT2 | LWAX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11); |
| 1177 #else |
| 1178 lwzx(rt, src); |
| 1179 #endif |
| 1180 } |
| 1181 |
| 1182 |
1123 void Assembler::stb(Register dst, const MemOperand& src) { | 1183 void Assembler::stb(Register dst, const MemOperand& src) { |
1124 DCHECK(!src.ra_.is(r0)); | 1184 DCHECK(!src.ra_.is(r0)); |
1125 d_form(STB, dst, src.ra(), src.offset(), true); | 1185 d_form(STB, dst, src.ra(), src.offset(), true); |
1126 } | 1186 } |
1127 | 1187 |
1128 | 1188 |
1129 void Assembler::stbx(Register rs, const MemOperand& src) { | 1189 void Assembler::stbx(Register rs, const MemOperand& src) { |
1130 Register ra = src.ra(); | 1190 Register ra = src.ra(); |
1131 Register rb = src.rb(); | 1191 Register rb = src.rb(); |
1132 DCHECK(!ra.is(r0)); | 1192 DCHECK(!ra.is(r0)); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 void Assembler::extsb(Register rs, Register ra, RCBit rc) { | 1261 void Assembler::extsb(Register rs, Register ra, RCBit rc) { |
1202 emit(EXT2 | EXTSB | ra.code() * B21 | rs.code() * B16 | rc); | 1262 emit(EXT2 | EXTSB | ra.code() * B21 | rs.code() * B16 | rc); |
1203 } | 1263 } |
1204 | 1264 |
1205 | 1265 |
1206 void Assembler::extsh(Register rs, Register ra, RCBit rc) { | 1266 void Assembler::extsh(Register rs, Register ra, RCBit rc) { |
1207 emit(EXT2 | EXTSH | ra.code() * B21 | rs.code() * B16 | rc); | 1267 emit(EXT2 | EXTSH | ra.code() * B21 | rs.code() * B16 | rc); |
1208 } | 1268 } |
1209 | 1269 |
1210 | 1270 |
| 1271 void Assembler::extsw(Register rs, Register ra, RCBit rc) { |
| 1272 #if V8_TARGET_ARCH_PPC64 |
| 1273 emit(EXT2 | EXTSW | ra.code() * B21 | rs.code() * B16 | rc); |
| 1274 #else |
| 1275 // nop on 32-bit |
| 1276 DCHECK(rs.is(ra) && rc == LeaveRC); |
| 1277 #endif |
| 1278 } |
| 1279 |
| 1280 |
1211 void Assembler::neg(Register rt, Register ra, OEBit o, RCBit r) { | 1281 void Assembler::neg(Register rt, Register ra, OEBit o, RCBit r) { |
1212 emit(EXT2 | NEGX | rt.code() * B21 | ra.code() * B16 | o | r); | 1282 emit(EXT2 | NEGX | rt.code() * B21 | ra.code() * B16 | o | r); |
1213 } | 1283 } |
1214 | 1284 |
1215 | 1285 |
1216 void Assembler::andc(Register dst, Register src1, Register src2, RCBit rc) { | 1286 void Assembler::andc(Register dst, Register src1, Register src2, RCBit rc) { |
1217 x_form(EXT2 | ANDCX, dst, src1, src2, rc); | 1287 x_form(EXT2 | ANDCX, dst, src1, src2, rc); |
1218 } | 1288 } |
1219 | 1289 |
1220 | 1290 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 void Assembler::rotrdi(Register ra, Register rs, int sh, RCBit r) { | 1446 void Assembler::rotrdi(Register ra, Register rs, int sh, RCBit r) { |
1377 rldicl(ra, rs, 64 - sh, 0, r); | 1447 rldicl(ra, rs, 64 - sh, 0, r); |
1378 } | 1448 } |
1379 | 1449 |
1380 | 1450 |
1381 void Assembler::cntlzd_(Register ra, Register rs, RCBit rc) { | 1451 void Assembler::cntlzd_(Register ra, Register rs, RCBit rc) { |
1382 x_form(EXT2 | CNTLZDX, ra, rs, r0, rc); | 1452 x_form(EXT2 | CNTLZDX, ra, rs, r0, rc); |
1383 } | 1453 } |
1384 | 1454 |
1385 | 1455 |
1386 void Assembler::extsw(Register rs, Register ra, RCBit rc) { | |
1387 emit(EXT2 | EXTSW | ra.code() * B21 | rs.code() * B16 | rc); | |
1388 } | |
1389 | |
1390 | |
1391 void Assembler::mulld(Register dst, Register src1, Register src2, OEBit o, | 1456 void Assembler::mulld(Register dst, Register src1, Register src2, OEBit o, |
1392 RCBit r) { | 1457 RCBit r) { |
1393 xo_form(EXT2 | MULLD, dst, src1, src2, o, r); | 1458 xo_form(EXT2 | MULLD, dst, src1, src2, o, r); |
1394 } | 1459 } |
1395 | 1460 |
1396 | 1461 |
1397 void Assembler::divd(Register dst, Register src1, Register src2, OEBit o, | 1462 void Assembler::divd(Register dst, Register src1, Register src2, OEBit o, |
1398 RCBit r) { | 1463 RCBit r) { |
1399 xo_form(EXT2 | DIVD, dst, src1, src2, o, r); | 1464 xo_form(EXT2 | DIVD, dst, src1, src2, o, r); |
1400 } | 1465 } |
| 1466 |
| 1467 |
| 1468 void Assembler::divdu(Register dst, Register src1, Register src2, OEBit o, |
| 1469 RCBit r) { |
| 1470 xo_form(EXT2 | DIVDU, dst, src1, src2, o, r); |
| 1471 } |
1401 #endif | 1472 #endif |
1402 | 1473 |
1403 | 1474 |
1404 void Assembler::fake_asm(enum FAKE_OPCODE_T fopcode) { | |
1405 DCHECK(fopcode < fLastFaker); | |
1406 emit(FAKE_OPCODE | FAKER_SUBOPCODE | fopcode); | |
1407 } | |
1408 | |
1409 | |
1410 void Assembler::marker_asm(int mcode) { | |
1411 if (::v8::internal::FLAG_trace_sim_stubs) { | |
1412 DCHECK(mcode < F_NEXT_AVAILABLE_STUB_MARKER); | |
1413 emit(FAKE_OPCODE | MARKER_SUBOPCODE | mcode); | |
1414 } | |
1415 } | |
1416 | |
1417 | |
1418 // Function descriptor for AIX. | 1475 // Function descriptor for AIX. |
1419 // Code address skips the function descriptor "header". | 1476 // Code address skips the function descriptor "header". |
1420 // TOC and static chain are ignored and set to 0. | 1477 // TOC and static chain are ignored and set to 0. |
1421 void Assembler::function_descriptor() { | 1478 void Assembler::function_descriptor() { |
1422 #if ABI_USES_FUNCTION_DESCRIPTORS | 1479 #if ABI_USES_FUNCTION_DESCRIPTORS |
1423 DCHECK(pc_offset() == 0); | 1480 DCHECK(pc_offset() == 0); |
1424 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); | 1481 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); |
1425 emit_ptr(reinterpret_cast<uintptr_t>(pc_) + 3 * kPointerSize); | 1482 emit_ptr(reinterpret_cast<uintptr_t>(pc_) + 3 * kPointerSize); |
1426 emit_ptr(0); | 1483 emit_ptr(0); |
1427 emit_ptr(0); | 1484 emit_ptr(0); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1537 // and only use the generic version when we require a fixed sequence | 1594 // and only use the generic version when we require a fixed sequence |
1538 void Assembler::mov(Register dst, const Operand& src) { | 1595 void Assembler::mov(Register dst, const Operand& src) { |
1539 intptr_t value = src.immediate(); | 1596 intptr_t value = src.immediate(); |
1540 bool canOptimize; | 1597 bool canOptimize; |
1541 RelocInfo rinfo(pc_, src.rmode_, value, NULL); | 1598 RelocInfo rinfo(pc_, src.rmode_, value, NULL); |
1542 | 1599 |
1543 if (src.must_output_reloc_info(this)) { | 1600 if (src.must_output_reloc_info(this)) { |
1544 RecordRelocInfo(rinfo); | 1601 RecordRelocInfo(rinfo); |
1545 } | 1602 } |
1546 | 1603 |
1547 canOptimize = | 1604 canOptimize = !(src.must_output_reloc_info(this) || |
1548 !(src.must_output_reloc_info(this) || is_trampoline_pool_blocked()); | 1605 (is_trampoline_pool_blocked() && !is_int16(value))); |
1549 | 1606 |
1550 #if V8_OOL_CONSTANT_POOL | 1607 #if V8_OOL_CONSTANT_POOL |
1551 if (use_constant_pool_for_mov(src, canOptimize)) { | 1608 if (use_constant_pool_for_mov(src, canOptimize)) { |
1552 DCHECK(is_ool_constant_pool_available()); | 1609 DCHECK(is_ool_constant_pool_available()); |
1553 ConstantPoolAddEntry(rinfo); | 1610 ConstantPoolAddEntry(rinfo); |
1554 #if V8_TARGET_ARCH_PPC64 | 1611 #if V8_TARGET_ARCH_PPC64 |
1555 BlockTrampolinePoolScope block_trampoline_pool(this); | 1612 BlockTrampolinePoolScope block_trampoline_pool(this); |
1556 // We are forced to use 2 instruction sequence since the constant | 1613 // We are forced to use 2 instruction sequence since the constant |
1557 // pool pointer is tagged. | 1614 // pool pointer is tagged. |
1558 li(dst, Operand::Zero()); | 1615 li(dst, Operand::Zero()); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1734 bind(&skip); | 1791 bind(&skip); |
1735 } else { | 1792 } else { |
1736 bkpt(0); | 1793 bkpt(0); |
1737 } | 1794 } |
1738 } | 1795 } |
1739 | 1796 |
1740 | 1797 |
1741 void Assembler::bkpt(uint32_t imm16) { emit(0x7d821008); } | 1798 void Assembler::bkpt(uint32_t imm16) { emit(0x7d821008); } |
1742 | 1799 |
1743 | 1800 |
1744 void Assembler::info(const char* msg, Condition cond, int32_t code, | |
1745 CRegister cr) { | |
1746 if (::v8::internal::FLAG_trace_sim_stubs) { | |
1747 emit(0x7d9ff808); | |
1748 #if V8_TARGET_ARCH_PPC64 | |
1749 uint64_t value = reinterpret_cast<uint64_t>(msg); | |
1750 emit(static_cast<uint32_t>(value >> 32)); | |
1751 emit(static_cast<uint32_t>(value & 0xFFFFFFFF)); | |
1752 #else | |
1753 emit(reinterpret_cast<Instr>(msg)); | |
1754 #endif | |
1755 } | |
1756 } | |
1757 | |
1758 | |
1759 void Assembler::dcbf(Register ra, Register rb) { | 1801 void Assembler::dcbf(Register ra, Register rb) { |
1760 emit(EXT2 | DCBF | ra.code() * B16 | rb.code() * B11); | 1802 emit(EXT2 | DCBF | ra.code() * B16 | rb.code() * B11); |
1761 } | 1803 } |
1762 | 1804 |
1763 | 1805 |
1764 void Assembler::sync() { emit(EXT2 | SYNC); } | 1806 void Assembler::sync() { emit(EXT2 | SYNC); } |
1765 | 1807 |
1766 | 1808 |
1767 void Assembler::lwsync() { emit(EXT2 | SYNC | 1 * B21); } | 1809 void Assembler::lwsync() { emit(EXT2 | SYNC | 1 * B21); } |
1768 | 1810 |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1976 void Assembler::fctiwz(const DoubleRegister frt, const DoubleRegister frb) { | 2018 void Assembler::fctiwz(const DoubleRegister frt, const DoubleRegister frb) { |
1977 emit(EXT4 | FCTIWZ | frt.code() * B21 | frb.code() * B11); | 2019 emit(EXT4 | FCTIWZ | frt.code() * B21 | frb.code() * B11); |
1978 } | 2020 } |
1979 | 2021 |
1980 | 2022 |
1981 void Assembler::fctiw(const DoubleRegister frt, const DoubleRegister frb) { | 2023 void Assembler::fctiw(const DoubleRegister frt, const DoubleRegister frb) { |
1982 emit(EXT4 | FCTIW | frt.code() * B21 | frb.code() * B11); | 2024 emit(EXT4 | FCTIW | frt.code() * B21 | frb.code() * B11); |
1983 } | 2025 } |
1984 | 2026 |
1985 | 2027 |
1986 void Assembler::frim(const DoubleRegister frt, const DoubleRegister frb) { | 2028 void Assembler::frin(const DoubleRegister frt, const DoubleRegister frb, |
1987 emit(EXT4 | FRIM | frt.code() * B21 | frb.code() * B11); | 2029 RCBit rc) { |
| 2030 emit(EXT4 | FRIN | frt.code() * B21 | frb.code() * B11 | rc); |
1988 } | 2031 } |
1989 | 2032 |
1990 | 2033 |
| 2034 void Assembler::friz(const DoubleRegister frt, const DoubleRegister frb, |
| 2035 RCBit rc) { |
| 2036 emit(EXT4 | FRIZ | frt.code() * B21 | frb.code() * B11 | rc); |
| 2037 } |
| 2038 |
| 2039 |
| 2040 void Assembler::frip(const DoubleRegister frt, const DoubleRegister frb, |
| 2041 RCBit rc) { |
| 2042 emit(EXT4 | FRIP | frt.code() * B21 | frb.code() * B11 | rc); |
| 2043 } |
| 2044 |
| 2045 |
| 2046 void Assembler::frim(const DoubleRegister frt, const DoubleRegister frb, |
| 2047 RCBit rc) { |
| 2048 emit(EXT4 | FRIM | frt.code() * B21 | frb.code() * B11 | rc); |
| 2049 } |
| 2050 |
| 2051 |
1991 void Assembler::frsp(const DoubleRegister frt, const DoubleRegister frb, | 2052 void Assembler::frsp(const DoubleRegister frt, const DoubleRegister frb, |
1992 RCBit rc) { | 2053 RCBit rc) { |
1993 emit(EXT4 | FRSP | frt.code() * B21 | frb.code() * B11 | rc); | 2054 emit(EXT4 | FRSP | frt.code() * B21 | frb.code() * B11 | rc); |
1994 } | 2055 } |
1995 | 2056 |
1996 | 2057 |
1997 void Assembler::fcfid(const DoubleRegister frt, const DoubleRegister frb, | 2058 void Assembler::fcfid(const DoubleRegister frt, const DoubleRegister frb, |
1998 RCBit rc) { | 2059 RCBit rc) { |
1999 emit(EXT4 | FCFID | frt.code() * B21 | frb.code() * B11 | rc); | 2060 emit(EXT4 | FCFID | frt.code() * B21 | frb.code() * B11 | rc); |
2000 } | 2061 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2126 | 2187 |
2127 | 2188 |
2128 void Assembler::RecordComment(const char* msg) { | 2189 void Assembler::RecordComment(const char* msg) { |
2129 if (FLAG_code_comments) { | 2190 if (FLAG_code_comments) { |
2130 CheckBuffer(); | 2191 CheckBuffer(); |
2131 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); | 2192 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); |
2132 } | 2193 } |
2133 } | 2194 } |
2134 | 2195 |
2135 | 2196 |
| 2197 void Assembler::RecordDeoptReason(const int reason, const int raw_position) { |
| 2198 if (FLAG_trace_deopt) { |
| 2199 EnsureSpace ensure_space(this); |
| 2200 RecordRelocInfo(RelocInfo::POSITION, raw_position); |
| 2201 RecordRelocInfo(RelocInfo::DEOPT_REASON, reason); |
| 2202 } |
| 2203 } |
| 2204 |
| 2205 |
2136 void Assembler::GrowBuffer() { | 2206 void Assembler::GrowBuffer() { |
2137 if (!own_buffer_) FATAL("external code buffer is too small"); | 2207 if (!own_buffer_) FATAL("external code buffer is too small"); |
2138 | 2208 |
2139 // Compute new buffer size. | 2209 // Compute new buffer size. |
2140 CodeDesc desc; // the new buffer | 2210 CodeDesc desc; // the new buffer |
2141 if (buffer_size_ < 4 * KB) { | 2211 if (buffer_size_ < 4 * KB) { |
2142 desc.buffer_size = 4 * KB; | 2212 desc.buffer_size = 4 * KB; |
2143 } else if (buffer_size_ < 1 * MB) { | 2213 } else if (buffer_size_ < 1 * MB) { |
2144 desc.buffer_size = 2 * buffer_size_; | 2214 desc.buffer_size = 2 * buffer_size_; |
2145 } else { | 2215 } else { |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2483 | 2553 |
2484 // Patch load instruction with correct offset. | 2554 // Patch load instruction with correct offset. |
2485 Assembler::SetConstantPoolOffset(rinfo.pc(), offset); | 2555 Assembler::SetConstantPoolOffset(rinfo.pc(), offset); |
2486 } | 2556 } |
2487 } | 2557 } |
2488 #endif | 2558 #endif |
2489 } | 2559 } |
2490 } // namespace v8::internal | 2560 } // namespace v8::internal |
2491 | 2561 |
2492 #endif // V8_TARGET_ARCH_PPC | 2562 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |