40 #ifndef V8_PPC_ASSEMBLER_PPC_H_ 41 #define V8_PPC_ASSEMBLER_PPC_H_ 46 #include "src/assembler.h" 47 #include "src/constant-pool.h" 48 #include "src/double.h" 49 #include "src/external-reference.h" 50 #include "src/label.h" 51 #include "src/objects/smi.h" 52 #include "src/ppc/constants-ppc.h" 54 #if V8_HOST_ARCH_PPC && \ 55 (V8_OS_AIX || (V8_TARGET_ARCH_PPC64 && V8_TARGET_BIG_ENDIAN)) 56 #define ABI_USES_FUNCTION_DESCRIPTORS 1 58 #define ABI_USES_FUNCTION_DESCRIPTORS 0 61 #if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64 62 #define ABI_PASSES_HANDLES_IN_REGS 1 64 #define ABI_PASSES_HANDLES_IN_REGS 0 67 #if !V8_HOST_ARCH_PPC || !V8_TARGET_ARCH_PPC64 || V8_TARGET_LITTLE_ENDIAN 68 #define ABI_RETURNS_OBJECT_PAIRS_IN_REGS 1 70 #define ABI_RETURNS_OBJECT_PAIRS_IN_REGS 0 73 #if !V8_HOST_ARCH_PPC || (V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN) 74 #define ABI_CALL_VIA_IP 1 76 #define ABI_CALL_VIA_IP 0 79 #if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64 80 #define ABI_TOC_REGISTER 2 82 #define ABI_TOC_REGISTER 13 85 #define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC 91 #define GENERAL_REGISTERS(V) \ 92 V(r0) V(sp) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \ 93 V(r8) V(r9) V(r10) V(r11) V(ip) V(r13) V(r14) V(r15) \ 94 V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ 95 V(r24) V(r25) V(r26) V(r27) V(r28) V(r29) V(r30) V(fp) 97 #if V8_EMBEDDED_CONSTANT_POOL 98 #define ALLOCATABLE_GENERAL_REGISTERS(V) \ 99 V(r3) V(r4) V(r5) V(r6) V(r7) \ 100 V(r8) V(r9) V(r10) V(r14) V(r15) \ 101 V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ 102 V(r24) V(r25) V(r26) V(r27) V(r30) 104 #define ALLOCATABLE_GENERAL_REGISTERS(V) \ 105 V(r3) V(r4) V(r5) V(r6) V(r7) \ 106 V(r8) V(r9) V(r10) V(r14) V(r15) \ 107 V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ 108 V(r24) V(r25) V(r26) V(r27) V(r28) V(r30) 111 #define LOW_DOUBLE_REGISTERS(V) \ 112 V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ 113 V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) 115 #define NON_LOW_DOUBLE_REGISTERS(V) \ 116 V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \ 117 V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31) 119 #define DOUBLE_REGISTERS(V) \ 120 LOW_DOUBLE_REGISTERS(V) NON_LOW_DOUBLE_REGISTERS(V) 122 #define FLOAT_REGISTERS DOUBLE_REGISTERS 123 #define SIMD128_REGISTERS DOUBLE_REGISTERS 125 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 126 V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ 127 V(d8) V(d9) V(d10) V(d11) V(d12) V(d15) \ 128 V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \ 129 V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31) 131 #define C_REGISTERS(V) \ 132 V(cr0) V(cr1) V(cr2) V(cr3) V(cr4) V(cr5) V(cr6) V(cr7) \ 133 V(cr8) V(cr9) V(cr10) V(cr11) V(cr12) V(cr15) 138 const int kNumRegs = 32;
141 const RegList kJSCallerSaved = 1 << 3 |
151 const int kNumJSCallerSaved = 9;
155 int JSCallerSavedCode(
int n);
158 const RegList kCalleeSaved = 1 << 14 |
177 const int kNumCalleeSaved = 18;
179 const RegList kCallerSavedDoubles = 1 << 0 |
194 const int kNumCallerSavedDoubles = 14;
196 const RegList kCalleeSavedDoubles = 1 << 14 |
215 const int kNumCalleeSavedDoubles = 18;
219 const int kNumSafepointRegisters = 32;
224 #if V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN // ppc64le linux 234 const int kNumRequiredStackFrameSlots = 12;
235 const int kStackFrameLRSlot = 2;
236 const int kStackFrameExtraParamSlot = 12;
249 const int kNumRequiredStackFrameSlots = 14;
250 const int kStackFrameLRSlot = 2;
251 const int kStackFrameExtraParamSlot = 14;
257 const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
258 const int kNumSafepointSavedRegisters = kNumJSCallerSaved + kNumCalleeSaved;
261 #define REGISTER_CODE(R) kRegCode_##R, 262 GENERAL_REGISTERS(REGISTER_CODE)
267 class Register :
public RegisterBase<Register, kRegAfterLast> {
269 #if V8_TARGET_LITTLE_ENDIAN 270 static constexpr
int kMantissaOffset = 0;
271 static constexpr
int kExponentOffset = 4;
273 static constexpr
int kMantissaOffset = 4;
274 static constexpr
int kExponentOffset = 0;
278 friend class RegisterBase;
279 explicit constexpr Register(
int code) : RegisterBase(code) {}
282 ASSERT_TRIVIALLY_COPYABLE(Register);
283 static_assert(
sizeof(Register) ==
sizeof(
int),
284 "Register can efficiently be passed by value");
286 #define DEFINE_REGISTER(R) \ 287 constexpr Register R = Register::from_code<kRegCode_##R>(); 288 GENERAL_REGISTERS(DEFINE_REGISTER)
289 #undef DEFINE_REGISTER 290 constexpr Register no_reg = Register::no_reg();
293 constexpr Register kConstantPoolRegister = r28;
294 constexpr Register kRootRegister = r29;
295 constexpr Register cp = r30;
297 constexpr
bool kPadArguments =
false;
298 constexpr
bool kSimpleFPAliasing =
true;
299 constexpr
bool kSimdMaskRegisters =
false;
301 enum DoubleRegisterCode {
302 #define REGISTER_CODE(R) kDoubleCode_##R, 303 DOUBLE_REGISTERS(REGISTER_CODE)
315 static constexpr
int kSizeInBytes = 8;
316 inline static int NumRegisters();
325 "DoubleRegister can efficiently be passed by value");
332 #define DEFINE_REGISTER(R) \ 333 constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>(); 334 DOUBLE_REGISTERS(DEFINE_REGISTER)
335 #undef DEFINE_REGISTER 346 #define REGISTER_CODE(R) kCCode_##R, 347 C_REGISTERS(REGISTER_CODE)
353 class CRegister :
public RegisterBase<CRegister, kCAfterLast> {
354 friend class RegisterBase;
355 explicit constexpr CRegister(
int code) : RegisterBase(code) {}
358 constexpr CRegister no_creg = CRegister::no_reg();
359 #define DECLARE_C_REGISTER(R) \ 360 constexpr CRegister R = CRegister::from_code<kCCode_##R>(); 361 C_REGISTERS(DECLARE_C_REGISTER)
362 #undef DECLARE_C_REGISTER 371 V8_INLINE
explicit Operand(intptr_t immediate,
372 RelocInfo::Mode rmode = RelocInfo::NONE)
374 value_.immediate = immediate;
376 V8_INLINE
static Operand Zero() {
return Operand(static_cast<intptr_t>(0)); }
377 V8_INLINE
explicit Operand(
const ExternalReference& f)
378 : rmode_(RelocInfo::EXTERNAL_REFERENCE) {
379 value_.immediate =
static_cast<intptr_t
>(f.address());
381 explicit Operand(Handle<HeapObject> handle);
382 V8_INLINE
explicit Operand(Smi value) : rmode_(RelocInfo::NONE) {
383 value_.immediate =
static_cast<intptr_t
>(value.ptr());
386 V8_INLINE
explicit Operand(Register rm);
388 static Operand EmbeddedNumber(
double number);
389 static Operand EmbeddedStringConstant(
const StringConstantBase* str);
390 static Operand EmbeddedCode(CodeStub* stub);
393 V8_INLINE
bool is_reg()
const {
return rm_.is_valid(); }
395 bool must_output_reloc_info(
const Assembler* assembler)
const;
397 inline intptr_t immediate()
const {
398 DCHECK(IsImmediate());
399 DCHECK(!IsHeapObjectRequest());
400 return value_.immediate;
402 bool IsImmediate()
const {
return !rm_.is_valid(); }
404 HeapObjectRequest heap_object_request()
const {
405 DCHECK(IsHeapObjectRequest());
406 return value_.heap_object_request;
409 Register rm()
const {
return rm_; }
411 bool IsHeapObjectRequest()
const {
412 DCHECK_IMPLIES(is_heap_object_request_, IsImmediate());
413 DCHECK_IMPLIES(is_heap_object_request_,
414 rmode_ == RelocInfo::EMBEDDED_OBJECT ||
415 rmode_ == RelocInfo::CODE_TARGET);
416 return is_heap_object_request_;
420 Register rm_ = no_reg;
423 HeapObjectRequest heap_object_request;
426 bool is_heap_object_request_ =
false;
428 RelocInfo::Mode rmode_;
430 friend class Assembler;
431 friend class MacroAssembler;
440 explicit MemOperand(Register rn, int32_t offset = 0);
442 explicit MemOperand(Register ra, Register rb);
444 int32_t offset()
const {
449 Register ra()
const {
453 Register rb()
const {
462 friend class Assembler;
470 : position_(position), rmode_(rmode), data_(data) {}
472 int position()
const {
return position_; }
473 RelocInfo::Mode rmode()
const {
return rmode_; }
474 intptr_t data()
const {
return data_; }
478 RelocInfo::Mode rmode_;
505 void GetCode(Isolate* isolate, CodeDesc* desc);
531 bool is_near(Label* L, Condition cond);
535 int branch_offset(Label* L) {
536 if (L->is_unused() && !trampoline_emitted_) {
539 return link(L) - pc_offset();
544 void label_at_put(Label* L,
int at_offset);
546 V8_INLINE
static bool IsConstantPoolLoadStart(
547 Address pc, ConstantPoolEntry::Access* access =
nullptr);
548 V8_INLINE
static bool IsConstantPoolLoadEnd(
549 Address pc, ConstantPoolEntry::Access* access =
nullptr);
550 V8_INLINE
static int GetConstantPoolOffset(Address pc,
551 ConstantPoolEntry::Access access,
552 ConstantPoolEntry::Type type);
553 V8_INLINE
void PatchConstantPoolAccessInstruction(
554 int pc_offset,
int offset, ConstantPoolEntry::Access access,
555 ConstantPoolEntry::Type type);
559 V8_INLINE
static Address target_constant_pool_address_at(
560 Address pc, Address constant_pool, ConstantPoolEntry::Access access,
561 ConstantPoolEntry::Type type);
565 V8_INLINE
static Address target_address_at(Address pc, Address constant_pool);
566 V8_INLINE
static void set_target_address_at(
567 Address pc, Address constant_pool, Address target,
568 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
572 inline static Address target_address_from_return_address(Address pc);
576 V8_INLINE
static Address return_address_from_call_start(Address pc);
580 inline static void deserialization_set_special_target_at(
581 Address instruction_payload, Code code, Address target);
584 inline static int deserialization_special_target_size(
585 Address instruction_payload);
588 inline static void deserialization_set_target_internal_reference_at(
589 Address pc, Address target,
590 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
598 static constexpr
int kSpecialTargetSize = 0;
601 #if V8_TARGET_ARCH_PPC64 602 static constexpr
int kMovInstructionsConstantPool = 1;
603 static constexpr
int kMovInstructionsNoConstantPool = 5;
604 #if defined(V8_PPC_TAGGING_OPT) 605 static constexpr
int kTaggedLoadInstructions = 1;
607 static constexpr
int kTaggedLoadInstructions = 2;
610 static constexpr
int kMovInstructionsConstantPool = 1;
611 static constexpr
int kMovInstructionsNoConstantPool = 2;
612 static constexpr
int kTaggedLoadInstructions = 1;
614 static constexpr
int kMovInstructions = FLAG_enable_embedded_constant_pool
615 ? kMovInstructionsConstantPool
616 : kMovInstructionsNoConstantPool;
626 static constexpr
int kCallTargetAddressOffset =
627 (kMovInstructions + 2) * kInstrSize;
629 static inline int encode_crbit(
const CRegister& cr,
enum CRBit crbit) {
630 return ((cr.code() * CRWIDTH) + crbit);
633 #define DECLARE_PPC_X_INSTRUCTIONS_A_FORM(name, instr_name, instr_value) \ 634 inline void name(const Register rt, const Register ra, \ 635 const Register rb, const RCBit rc = LeaveRC) { \ 636 x_form(instr_name, rt, ra, rb, rc); \ 639 #define DECLARE_PPC_X_INSTRUCTIONS_B_FORM(name, instr_name, instr_value) \ 640 inline void name(const Register ra, const Register rs, \ 641 const Register rb, const RCBit rc = LeaveRC) { \ 642 x_form(instr_name, rs, ra, rb, rc); \ 645 #define DECLARE_PPC_X_INSTRUCTIONS_C_FORM(name, instr_name, instr_value) \ 646 inline void name(const Register dst, const Register src, \ 647 const RCBit rc = LeaveRC) { \ 648 x_form(instr_name, src, dst, r0, rc); \ 651 #define DECLARE_PPC_X_INSTRUCTIONS_D_FORM(name, instr_name, instr_value) \ 653 inline void name(const R rt, const Register ra, const Register rb, \ 654 const RCBit rc = LeaveRC) { \ 655 x_form(instr_name, rt.code(), ra.code(), rb.code(), rc); \ 658 inline void name(const R dst, const MemOperand& src) { \ 659 name(dst, src.ra(), src.rb()); \ 662 #define DECLARE_PPC_X_INSTRUCTIONS_E_FORM(name, instr_name, instr_value) \ 663 inline void name(const Register dst, const Register src, \ 664 const int sh, const RCBit rc = LeaveRC) { \ 665 x_form(instr_name, src.code(), dst.code(), sh, rc); \ 668 #define DECLARE_PPC_X_INSTRUCTIONS_F_FORM(name, instr_name, instr_value) \ 669 inline void name(const Register src1, const Register src2, \ 670 const CRegister cr = cr7, const RCBit rc = LeaveRC) { \ 671 x_form(instr_name, cr, src1, src2, rc); \ 673 inline void name##w(const Register src1, const Register src2, \ 674 const CRegister cr = cr7, const RCBit rc = LeaveRC) { \ 675 x_form(instr_name, cr.code() * B2, src1.code(), src2.code(), LeaveRC); \ 678 #define DECLARE_PPC_X_INSTRUCTIONS_EH_S_FORM(name, instr_name, instr_value) \ 679 inline void name(const Register dst, const MemOperand& src) { \ 680 x_form(instr_name, src.ra(), dst, src.rb(), SetEH); \ 682 #define DECLARE_PPC_X_INSTRUCTIONS_EH_L_FORM(name, instr_name, instr_value) \ 683 inline void name(const Register dst, const MemOperand& src) { \ 684 DCHECK(src.ra_ != r0); \ 685 x_form(instr_name, src.ra(), dst, src.rb(), SetEH); \ 688 inline void x_form(Instr instr,
int f1,
int f2,
int f3,
int rc) {
689 emit(instr | f1 * B21 | f2 * B16 | f3 * B11 | rc);
691 inline void x_form(Instr instr, Register rs, Register ra, Register rb,
693 emit(instr | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | rc);
695 inline void x_form(Instr instr, Register ra, Register rs, Register rb,
697 emit(instr | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | eh);
699 inline void x_form(Instr instr, CRegister cr, Register s1, Register s2,
701 #if V8_TARGET_ARCH_PPC64 706 emit(instr | cr.code() * B23 | L * B21 | s1.code() * B16 |
707 s2.code() * B11 | rc);
710 PPC_X_OPCODE_A_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_A_FORM)
711 PPC_X_OPCODE_B_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_B_FORM)
712 PPC_X_OPCODE_C_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_C_FORM)
713 PPC_X_OPCODE_D_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_D_FORM)
714 PPC_X_OPCODE_E_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_E_FORM)
715 PPC_X_OPCODE_F_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_F_FORM)
716 PPC_X_OPCODE_EH_S_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_EH_S_FORM)
717 PPC_X_OPCODE_EH_L_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_EH_L_FORM)
719 inline void notx(Register dst, Register src, RCBit rc = LeaveRC) {
720 nor(dst, src, src, rc);
722 inline void lwax(Register rt,
const MemOperand& src) {
723 #if V8_TARGET_ARCH_PPC64 724 Register ra = src.ra();
725 Register rb = src.rb();
727 x_form(LWAX, rt, ra, rb, LeaveRC);
732 inline void extsw(Register rs, Register ra, RCBit rc = LeaveRC) {
733 #if V8_TARGET_ARCH_PPC64 734 emit(EXT2 | EXTSW | ra.code() * B21 | rs.code() * B16 | rc);
737 DCHECK(rs == ra && rc == LeaveRC);
741 #undef DECLARE_PPC_X_INSTRUCTIONS_A_FORM 742 #undef DECLARE_PPC_X_INSTRUCTIONS_B_FORM 743 #undef DECLARE_PPC_X_INSTRUCTIONS_C_FORM 744 #undef DECLARE_PPC_X_INSTRUCTIONS_D_FORM 745 #undef DECLARE_PPC_X_INSTRUCTIONS_E_FORM 746 #undef DECLARE_PPC_X_INSTRUCTIONS_F_FORM 747 #undef DECLARE_PPC_X_INSTRUCTIONS_EH_S_FORM 748 #undef DECLARE_PPC_X_INSTRUCTIONS_EH_L_FORM 750 #define DECLARE_PPC_XX3_INSTRUCTIONS(name, instr_name, instr_value) \ 751 inline void name(const DoubleRegister rt, const DoubleRegister ra, \ 752 const DoubleRegister rb) { \ 753 xx3_form(instr_name, rt, ra, rb); \ 756 inline void xx3_form(Instr instr, DoubleRegister t, DoubleRegister a,
758 int AX = ((a.code() & 0x20) >> 5) & 0x1;
759 int BX = ((b.code() & 0x20) >> 5) & 0x1;
760 int TX = ((t.code() & 0x20) >> 5) & 0x1;
762 emit(instr | (t.code() & 0x1F) * B21 | (a.code() & 0x1F) * B16 |
763 (b.code() & 0x1F) * B11 | AX * B2 | BX * B1 | TX);
766 PPC_XX3_OPCODE_LIST(DECLARE_PPC_XX3_INSTRUCTIONS)
767 #undef DECLARE_PPC_XX3_INSTRUCTIONS 778 void DataAlign(
int m);
780 void CodeTargetAlign();
783 void bclr(BOfield bo,
int condition_bit, LKBit lk);
785 void bc(
int branch_offset, BOfield bo,
int condition_bit, LKBit lk = LeaveLK);
786 void b(
int branch_offset, LKBit lk);
788 void bcctr(BOfield bo,
int condition_bit, LKBit lk);
793 void b(Label* L, LKBit lk = LeaveLK) { b(branch_offset(L), lk); }
795 inline CRegister cmpi_optimization(CRegister cr) {
799 unsigned int sradi_mask = kOpcodeMask | kExt2OpcodeVariant2Mask;
800 unsigned int srawi_mask = kOpcodeMask | kExt2OpcodeMask;
801 int pos = pc_offset();
802 int cmpi_pos = pc_offset() - kInstrSize;
804 if (cmpi_pos > 0 && optimizable_cmpi_pos_ == cmpi_pos &&
805 cmpi_cr_.code() == cr.code() && last_bound_pos_ != pos) {
806 int xpos = cmpi_pos - kInstrSize;
807 int xinstr = instr_at(xpos);
808 int cmpi_ra = (instr_at(cmpi_pos) & 0x1f0000) >> 16;
810 int ra = (xinstr & 0x1f0000) >> 16;
812 if ((xinstr & sradi_mask) == (EXT2 | SRADIX)) {
814 instr_at_put(xpos, xinstr | SetRC);
816 }
else if ((xinstr & srawi_mask) == (EXT2 | SRAWIX)) {
818 instr_at_put(xpos, xinstr | SetRC);
820 }
else if ((xinstr & kOpcodeMask) == ANDIx) {
831 void bc_short(Condition cond, Label* L, CRegister cr = cr7,
832 LKBit lk = LeaveLK) {
834 DCHECK(cr.code() >= 0 && cr.code() <= 7);
836 cr = cmpi_optimization(cr);
838 int b_offset = branch_offset(L);
842 bc(b_offset, BT, encode_crbit(cr, CR_EQ), lk);
845 bc(b_offset, BF, encode_crbit(cr, CR_EQ), lk);
848 bc(b_offset, BT, encode_crbit(cr, CR_GT), lk);
851 bc(b_offset, BF, encode_crbit(cr, CR_GT), lk);
854 bc(b_offset, BT, encode_crbit(cr, CR_LT), lk);
857 bc(b_offset, BF, encode_crbit(cr, CR_LT), lk);
860 bc(b_offset, BT, encode_crbit(cr, CR_FU), lk);
863 bc(b_offset, BF, encode_crbit(cr, CR_FU), lk);
866 bc(b_offset, BT, encode_crbit(cr, CR_SO), lk);
869 bc(b_offset, BF, encode_crbit(cr, CR_SO), lk);
876 void bclr(Condition cond, CRegister cr = cr7, LKBit lk = LeaveLK) {
878 DCHECK(cr.code() >= 0 && cr.code() <= 7);
880 cr = cmpi_optimization(cr);
884 bclr(BT, encode_crbit(cr, CR_EQ), lk);
887 bclr(BF, encode_crbit(cr, CR_EQ), lk);
890 bclr(BT, encode_crbit(cr, CR_GT), lk);
893 bclr(BF, encode_crbit(cr, CR_GT), lk);
896 bclr(BT, encode_crbit(cr, CR_LT), lk);
899 bclr(BF, encode_crbit(cr, CR_LT), lk);
902 bclr(BT, encode_crbit(cr, CR_FU), lk);
905 bclr(BF, encode_crbit(cr, CR_FU), lk);
908 bclr(BT, encode_crbit(cr, CR_SO), lk);
911 bclr(BF, encode_crbit(cr, CR_SO), lk);
918 void isel(Register rt, Register ra, Register rb,
int cb);
919 void isel(Condition cond, Register rt, Register ra, Register rb,
920 CRegister cr = cr7) {
922 DCHECK(cr.code() >= 0 && cr.code() <= 7);
924 cr = cmpi_optimization(cr);
928 isel(rt, ra, rb, encode_crbit(cr, CR_EQ));
931 isel(rt, rb, ra, encode_crbit(cr, CR_EQ));
934 isel(rt, ra, rb, encode_crbit(cr, CR_GT));
937 isel(rt, rb, ra, encode_crbit(cr, CR_GT));
940 isel(rt, ra, rb, encode_crbit(cr, CR_LT));
943 isel(rt, rb, ra, encode_crbit(cr, CR_LT));
946 isel(rt, ra, rb, encode_crbit(cr, CR_FU));
949 isel(rt, rb, ra, encode_crbit(cr, CR_FU));
952 isel(rt, ra, rb, encode_crbit(cr, CR_SO));
955 isel(rt, rb, ra, encode_crbit(cr, CR_SO));
962 void b(Condition cond, Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
968 if ((L->is_bound() && is_near(L, cond)) || !is_trampoline_emitted()) {
969 bc_short(cond, L, cr, lk);
974 Condition neg_cond = NegateCondition(cond);
975 bc_short(neg_cond, &skip, cr);
980 void bne(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
983 void beq(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
986 void blt(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
989 void bge(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
992 void ble(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
995 void bgt(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
998 void bunordered(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
999 b(unordered, L, cr, lk);
1001 void bordered(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
1002 b(ordered, L, cr, lk);
1004 void boverflow(Label* L, CRegister cr = cr0, LKBit lk = LeaveLK) {
1005 b(overflow, L, cr, lk);
1007 void bnooverflow(Label* L, CRegister cr = cr0, LKBit lk = LeaveLK) {
1008 b(nooverflow, L, cr, lk);
1012 void bdnz(Label* L, LKBit lk = LeaveLK) {
1013 bc(branch_offset(L), DCBNZ, 0, lk);
1018 void sub(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
1021 void subc(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
1023 void sube(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
1026 void subfic(Register dst, Register src,
const Operand& imm);
1028 void add(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
1031 void addc(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
1033 void adde(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
1035 void addze(Register dst, Register src1, OEBit o = LeaveOE, RCBit r = LeaveRC);
1037 void mullw(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
1040 void mulhw(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
1041 void mulhwu(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
1043 void divw(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
1045 void divwu(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
1048 void addi(Register dst, Register src,
const Operand& imm);
1049 void addis(Register dst, Register src,
const Operand& imm);
1050 void addic(Register dst, Register src,
const Operand& imm);
1052 void andi(Register ra, Register rs,
const Operand& imm);
1053 void andis(Register ra, Register rs,
const Operand& imm);
1054 void ori(Register dst, Register src,
const Operand& imm);
1055 void oris(Register dst, Register src,
const Operand& imm);
1056 void xori(Register dst, Register src,
const Operand& imm);
1057 void xoris(Register ra, Register rs,
const Operand& imm);
1058 void cmpi(Register src1,
const Operand& src2, CRegister cr = cr7);
1059 void cmpli(Register src1,
const Operand& src2, CRegister cr = cr7);
1060 void cmpwi(Register src1,
const Operand& src2, CRegister cr = cr7);
1061 void cmplwi(Register src1,
const Operand& src2, CRegister cr = cr7);
1062 void li(Register dst,
const Operand& src);
1063 void lis(Register dst,
const Operand& imm);
1064 void mr(Register dst, Register src);
1066 void lbz(Register dst,
const MemOperand& src);
1067 void lhz(Register dst,
const MemOperand& src);
1068 void lha(Register dst,
const MemOperand& src);
1069 void lwz(Register dst,
const MemOperand& src);
1070 void lwzu(Register dst,
const MemOperand& src);
1071 void lwa(Register dst,
const MemOperand& src);
1072 void stb(Register dst,
const MemOperand& src);
1073 void sth(Register dst,
const MemOperand& src);
1074 void stw(Register dst,
const MemOperand& src);
1075 void stwu(Register dst,
const MemOperand& src);
1076 void neg(Register rt, Register ra, OEBit o = LeaveOE, RCBit c = LeaveRC);
1078 #if V8_TARGET_ARCH_PPC64 1079 void ld(Register rd,
const MemOperand& src);
1080 void ldu(Register rd,
const MemOperand& src);
1081 void std(Register rs,
const MemOperand& src);
1082 void stdu(Register rs,
const MemOperand& src);
1083 void rldic(Register dst, Register src,
int sh,
int mb, RCBit r = LeaveRC);
1084 void rldicl(Register dst, Register src,
int sh,
int mb, RCBit r = LeaveRC);
1085 void rldcl(Register ra, Register rs, Register rb,
int mb, RCBit r = LeaveRC);
1086 void rldicr(Register dst, Register src,
int sh,
int me, RCBit r = LeaveRC);
1087 void rldimi(Register dst, Register src,
int sh,
int mb, RCBit r = LeaveRC);
1088 void sldi(Register dst, Register src,
const Operand& val, RCBit rc = LeaveRC);
1089 void srdi(Register dst, Register src,
const Operand& val, RCBit rc = LeaveRC);
1090 void clrrdi(Register dst, Register src,
const Operand& val,
1091 RCBit rc = LeaveRC);
1092 void clrldi(Register dst, Register src,
const Operand& val,
1093 RCBit rc = LeaveRC);
1094 void sradi(Register ra, Register rs,
int sh, RCBit r = LeaveRC);
1095 void rotld(Register ra, Register rs, Register rb, RCBit r = LeaveRC);
1096 void rotldi(Register ra, Register rs,
int sh, RCBit r = LeaveRC);
1097 void rotrdi(Register ra, Register rs,
int sh, RCBit r = LeaveRC);
1098 void mulld(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
1100 void divd(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
1102 void divdu(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
1106 void rlwinm(Register ra, Register rs,
int sh,
int mb,
int me,
1107 RCBit rc = LeaveRC);
1108 void rlwimi(Register ra, Register rs,
int sh,
int mb,
int me,
1109 RCBit rc = LeaveRC);
1110 void rlwnm(Register ra, Register rs, Register rb,
int mb,
int me,
1111 RCBit rc = LeaveRC);
1112 void slwi(Register dst, Register src,
const Operand& val, RCBit rc = LeaveRC);
1113 void srwi(Register dst, Register src,
const Operand& val, RCBit rc = LeaveRC);
1114 void clrrwi(Register dst, Register src,
const Operand& val,
1115 RCBit rc = LeaveRC);
1116 void clrlwi(Register dst, Register src,
const Operand& val,
1117 RCBit rc = LeaveRC);
1118 void rotlw(Register ra, Register rs, Register rb, RCBit r = LeaveRC);
1119 void rotlwi(Register ra, Register rs,
int sh, RCBit r = LeaveRC);
1120 void rotrwi(Register ra, Register rs,
int sh, RCBit r = LeaveRC);
1122 void subi(Register dst, Register src1,
const Operand& src2);
1124 void mov(Register dst,
const Operand& src);
1125 void bitwise_mov(Register dst, intptr_t value);
1126 void bitwise_mov32(Register dst, int32_t value);
1127 void bitwise_add32(Register dst, Register src, int32_t value);
1131 void mov_label_offset(Register dst, Label* label);
1134 void add_label_offset(Register dst, Register base, Label* label,
1139 void mov_label_addr(Register dst, Label* label);
1143 void emit_label_addr(Label* label);
1146 void mul(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
1152 void crxor(
int bt,
int ba,
int bb);
1153 void crclr(
int bt) { crxor(bt, bt, bt); }
1154 void creqv(
int bt,
int ba,
int bb);
1155 void crset(
int bt) { creqv(bt, bt, bt); }
1156 void mflr(Register dst);
1157 void mtlr(Register src);
1158 void mtctr(Register src);
1159 void mtxer(Register src);
1160 void mcrfs(CRegister cr, FPSCRBit bit);
1161 void mfcr(Register dst);
1162 #if V8_TARGET_ARCH_PPC64 1163 void mffprd(Register dst, DoubleRegister src);
1164 void mffprwz(Register dst, DoubleRegister src);
1165 void mtfprd(DoubleRegister dst, Register src);
1166 void mtfprwz(DoubleRegister dst, Register src);
1167 void mtfprwa(DoubleRegister dst, Register src);
1170 void function_descriptor();
1173 void stop(
const char* msg, Condition cond = al,
1174 int32_t code = kDefaultStopCode, CRegister cr = cr7);
1178 void dcbf(Register ra, Register rb);
1181 void icbi(Register ra, Register rb);
1185 void lfd(
const DoubleRegister frt,
const MemOperand& src);
1186 void lfdu(
const DoubleRegister frt,
const MemOperand& src);
1187 void lfs(
const DoubleRegister frt,
const MemOperand& src);
1188 void lfsu(
const DoubleRegister frt,
const MemOperand& src);
1189 void stfd(
const DoubleRegister frs,
const MemOperand& src);
1190 void stfdu(
const DoubleRegister frs,
const MemOperand& src);
1191 void stfs(
const DoubleRegister frs,
const MemOperand& src);
1192 void stfsu(
const DoubleRegister frs,
const MemOperand& src);
1194 void fadd(
const DoubleRegister frt,
const DoubleRegister fra,
1195 const DoubleRegister frb, RCBit rc = LeaveRC);
1196 void fsub(
const DoubleRegister frt,
const DoubleRegister fra,
1197 const DoubleRegister frb, RCBit rc = LeaveRC);
1198 void fdiv(
const DoubleRegister frt,
const DoubleRegister fra,
1199 const DoubleRegister frb, RCBit rc = LeaveRC);
1200 void fmul(
const DoubleRegister frt,
const DoubleRegister fra,
1201 const DoubleRegister frc, RCBit rc = LeaveRC);
1202 void fcmpu(
const DoubleRegister fra,
const DoubleRegister frb,
1203 CRegister cr = cr7);
1204 void fmr(
const DoubleRegister frt,
const DoubleRegister frb,
1205 RCBit rc = LeaveRC);
1206 void fctiwz(
const DoubleRegister frt,
const DoubleRegister frb);
1207 void fctiw(
const DoubleRegister frt,
const DoubleRegister frb);
1208 void frin(
const DoubleRegister frt,
const DoubleRegister frb,
1209 RCBit rc = LeaveRC);
1210 void friz(
const DoubleRegister frt,
const DoubleRegister frb,
1211 RCBit rc = LeaveRC);
1212 void frip(
const DoubleRegister frt,
const DoubleRegister frb,
1213 RCBit rc = LeaveRC);
1214 void frim(
const DoubleRegister frt,
const DoubleRegister frb,
1215 RCBit rc = LeaveRC);
1216 void frsp(
const DoubleRegister frt,
const DoubleRegister frb,
1217 RCBit rc = LeaveRC);
1218 void fcfid(
const DoubleRegister frt,
const DoubleRegister frb,
1219 RCBit rc = LeaveRC);
1220 void fcfidu(
const DoubleRegister frt,
const DoubleRegister frb,
1221 RCBit rc = LeaveRC);
1222 void fcfidus(
const DoubleRegister frt,
const DoubleRegister frb,
1223 RCBit rc = LeaveRC);
1224 void fcfids(
const DoubleRegister frt,
const DoubleRegister frb,
1225 RCBit rc = LeaveRC);
1226 void fctid(
const DoubleRegister frt,
const DoubleRegister frb,
1227 RCBit rc = LeaveRC);
1228 void fctidz(
const DoubleRegister frt,
const DoubleRegister frb,
1229 RCBit rc = LeaveRC);
1230 void fctidu(
const DoubleRegister frt,
const DoubleRegister frb,
1231 RCBit rc = LeaveRC);
1232 void fctiduz(
const DoubleRegister frt,
const DoubleRegister frb,
1233 RCBit rc = LeaveRC);
1234 void fsel(
const DoubleRegister frt,
const DoubleRegister fra,
1235 const DoubleRegister frc,
const DoubleRegister frb,
1236 RCBit rc = LeaveRC);
1237 void fneg(
const DoubleRegister frt,
const DoubleRegister frb,
1238 RCBit rc = LeaveRC);
1239 void mtfsb0(FPSCRBit bit, RCBit rc = LeaveRC);
1240 void mtfsb1(FPSCRBit bit, RCBit rc = LeaveRC);
1241 void mtfsfi(
int bf,
int immediate, RCBit rc = LeaveRC);
1242 void mffs(
const DoubleRegister frt, RCBit rc = LeaveRC);
1243 void mtfsf(
const DoubleRegister frb,
bool L = 1,
int FLM = 0,
bool W = 0,
1244 RCBit rc = LeaveRC);
1245 void fsqrt(
const DoubleRegister frt,
const DoubleRegister frb,
1246 RCBit rc = LeaveRC);
1247 void fabs(
const DoubleRegister frt,
const DoubleRegister frb,
1248 RCBit rc = LeaveRC);
1249 void fmadd(
const DoubleRegister frt,
const DoubleRegister fra,
1250 const DoubleRegister frc,
const DoubleRegister frb,
1251 RCBit rc = LeaveRC);
1252 void fmsub(
const DoubleRegister frt,
const DoubleRegister fra,
1253 const DoubleRegister frc,
const DoubleRegister frb,
1254 RCBit rc = LeaveRC);
1260 enum NopMarkerTypes {
1261 NON_MARKING_NOP = 0,
1265 PROPERTY_ACCESS_INLINED,
1266 PROPERTY_ACCESS_INLINED_CONTEXT,
1267 PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
1270 FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
1273 void nop(
int type = 0);
1275 void push(Register src) {
1276 #if V8_TARGET_ARCH_PPC64 1277 stdu(src, MemOperand(sp, -kPointerSize));
1279 stwu(src, MemOperand(sp, -kPointerSize));
1283 void pop(Register dst) {
1284 #if V8_TARGET_ARCH_PPC64 1285 ld(dst, MemOperand(sp));
1287 lwz(dst, MemOperand(sp));
1289 addi(sp, sp, Operand(kPointerSize));
1292 void pop() { addi(sp, sp, Operand(kPointerSize)); }
1295 void jmp(Label* L) { b(L); }
1298 int SizeOfCodeGeneratedSince(Label* label) {
1299 return pc_offset() - label->pos();
1303 int InstructionsGeneratedSince(Label* label) {
1304 return SizeOfCodeGeneratedSince(label) / kInstrSize;
1308 class BlockTrampolinePoolScope {
1310 explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) {
1311 assem_->StartBlockTrampolinePool();
1313 ~BlockTrampolinePoolScope() { assem_->EndBlockTrampolinePool(); }
1318 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
1326 assem_->StartBlockConstantPoolEntrySharing();
1329 assem_->EndBlockConstantPoolEntrySharing();
1340 void RecordComment(
const char* msg);
1344 void RecordDeoptReason(DeoptimizeReason reason,
SourcePosition position,
1349 void db(uint8_t data);
1351 void dq(uint64_t data);
1355 Instr instr_at(
int pos) {
return *
reinterpret_cast<Instr*
>(buffer_ + pos); }
1356 void instr_at_put(
int pos, Instr instr) {
1357 *
reinterpret_cast<Instr*
>(buffer_ + pos) = instr;
1359 static Instr instr_at(Address pc) {
return *
reinterpret_cast<Instr*
>(pc); }
1360 static void instr_at_put(Address pc, Instr instr) {
1361 *
reinterpret_cast<Instr*
>(pc) = instr;
1363 static Condition GetCondition(Instr instr);
1365 static bool IsLis(Instr instr);
1366 static bool IsLi(Instr instr);
1367 static bool IsAddic(Instr instr);
1368 static bool IsOri(Instr instr);
1370 static bool IsBranch(Instr instr);
1371 static Register GetRA(Instr instr);
1372 static Register GetRB(Instr instr);
1373 #if V8_TARGET_ARCH_PPC64 1374 static bool Is64BitLoadIntoR12(Instr instr1, Instr instr2, Instr instr3,
1375 Instr instr4, Instr instr5);
1377 static bool Is32BitLoadIntoR12(Instr instr1, Instr instr2);
1380 static bool IsCmpRegister(Instr instr);
1381 static bool IsCmpImmediate(Instr instr);
1382 static bool IsRlwinm(Instr instr);
1383 static bool IsAndi(Instr instr);
1384 #if V8_TARGET_ARCH_PPC64 1385 static bool IsRldicl(Instr instr);
1387 static bool IsCrSet(Instr instr);
1388 static Register GetCmpImmediateRegister(Instr instr);
1389 static int GetCmpImmediateRawImmediate(Instr instr);
1390 static bool IsNop(Instr instr,
int type = NON_MARKING_NOP);
1394 void BlockTrampolinePoolFor(
int instructions);
1395 void CheckTrampolinePool();
1404 int instructions_required_for_mov(Register dst,
const Operand& src)
const;
1407 bool use_constant_pool_for_mov(Register dst,
const Operand& src,
1408 bool canOptimize)
const;
1415 void EnsureSpaceFor(
int space_needed);
1417 int EmitConstantPool() {
return constant_pool_builder_.Emit(
this); }
1419 bool ConstantPoolAccessIsInOverflow()
const {
1420 return constant_pool_builder_.NextAccess(ConstantPoolEntry::INTPTR) ==
1421 ConstantPoolEntry::OVERFLOWED;
1424 Label* ConstantPoolPosition() {
1425 return constant_pool_builder_.EmittedPosition();
1428 void EmitRelocations();
1431 int buffer_space()
const {
return reloc_info_writer.pos() - pc_; }
1435 int target_at(
int pos);
1438 void target_at_put(
int pos,
int target_pos,
bool* is_branch =
nullptr);
1441 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1442 ConstantPoolEntry::Access ConstantPoolAddEntry(RelocInfo::Mode rmode,
1445 RelocInfo::IsNone(rmode) ||
1446 (!options().record_reloc_info_for_serialization &&
1447 RelocInfo::IsShareableRelocMode(rmode) &&
1448 !is_constant_pool_entry_sharing_blocked() &&
1450 !RelocInfo::IsWasmCall(rmode) && !RelocInfo::IsWasmStubCall(rmode));
1451 return constant_pool_builder_.AddEntry(pc_offset(), value, sharing_ok);
1453 ConstantPoolEntry::Access ConstantPoolAddEntry(Double value) {
1454 return constant_pool_builder_.AddEntry(pc_offset(), value);
1458 void BlockTrampolinePoolBefore(
int pc_offset) {
1459 if (no_trampoline_pool_before_ < pc_offset)
1460 no_trampoline_pool_before_ = pc_offset;
1463 void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; }
1464 void EndBlockTrampolinePool() {
1465 int count = --trampoline_pool_blocked_nesting_;
1466 if (count == 0) CheckTrampolinePoolQuick();
1468 bool is_trampoline_pool_blocked()
const {
1469 return trampoline_pool_blocked_nesting_ > 0;
1472 void StartBlockConstantPoolEntrySharing() {
1473 constant_pool_entry_sharing_blocked_nesting_++;
1475 void EndBlockConstantPoolEntrySharing() {
1476 constant_pool_entry_sharing_blocked_nesting_--;
1478 bool is_constant_pool_entry_sharing_blocked()
const {
1479 return constant_pool_entry_sharing_blocked_nesting_ > 0;
1482 bool has_exception()
const {
return internal_trampoline_exception_; }
1484 bool is_trampoline_emitted()
const {
return trampoline_emitted_; }
1491 static constexpr
int kGap = 32;
1493 RelocInfoWriter reloc_info_writer;
1497 static const int kMaximalBufferSize = 512 * MB;
1502 int next_trampoline_check_;
1505 int trampoline_pool_blocked_nesting_;
1506 int no_trampoline_pool_before_;
1509 int constant_pool_entry_sharing_blocked_nesting_;
1513 static constexpr
int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1514 std::vector<DeferredRelocInfo> relocations_;
1517 int last_bound_pos_;
1519 int optimizable_cmpi_pos_;
1520 CRegister cmpi_cr_ = CRegister::no_reg();
1522 ConstantPoolBuilder constant_pool_builder_;
1524 void CheckBuffer() {
1525 if (buffer_space() <= kGap) {
1530 void GrowBuffer(
int needed = 0);
1532 void emit(Instr x) {
1534 *
reinterpret_cast<Instr*
>(pc_) = x;
1536 CheckTrampolinePoolQuick();
1538 void TrackBranch() {
1539 DCHECK(!trampoline_emitted_);
1540 int count = tracked_branch_count_++;
1544 next_trampoline_check_ =
1545 pc_offset() + kMaxCondBranchReach - kMaxBlockTrampolineSectionSize;
1547 next_trampoline_check_ -= kTrampolineSlotsSize;
1551 inline void UntrackBranch();
1552 void CheckTrampolinePoolQuick() {
1553 if (pc_offset() >= next_trampoline_check_) {
1554 CheckTrampolinePool();
1559 void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra,
1560 DoubleRegister frb, RCBit r);
1561 void d_form(Instr instr, Register rt, Register ra,
const intptr_t val,
1563 void xo_form(Instr instr, Register rt, Register ra, Register rb, OEBit o,
1565 void md_form(Instr instr, Register ra, Register rs,
int shift,
int maskbit,
1567 void mds_form(Instr instr, Register ra, Register rs, Register rb,
int maskbit,
1571 void print(Label* L);
1572 int max_reach_from(
int pos);
1573 void bind_to(Label* L,
int pos);
1574 void next(Label* L);
1580 free_slot_count_ = 0;
1582 Trampoline(
int start,
int slot_count) {
1584 free_slot_count_ = slot_count;
1587 int trampoline_slot = kInvalidSlotPos;
1588 if (free_slot_count_ <= 0) {
1595 trampoline_slot = next_slot_;
1597 next_slot_ += kTrampolineSlotsSize;
1599 return trampoline_slot;
1604 int free_slot_count_;
1607 int32_t get_trampoline_entry();
1608 int tracked_branch_count_;
1614 bool trampoline_emitted_;
1615 static constexpr
int kTrampolineSlotsSize = kInstrSize;
1616 static constexpr
int kMaxCondBranchReach = (1 << (16 - 1)) - 1;
1617 static constexpr
int kMaxBlockTrampolineSectionSize = 64 * kInstrSize;
1618 static constexpr
int kInvalidSlotPos = -1;
1620 Trampoline trampoline_;
1621 bool internal_trampoline_exception_;
1623 void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
1625 friend class RegExpMacroAssemblerPPC;
1626 friend class RelocInfo;
1627 friend class BlockTrampolinePoolScope;
1628 friend class EnsureSpace;
1633 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
1636 class PatchingAssembler :
public Assembler {
1638 PatchingAssembler(
const AssemblerOptions& options, byte* address,
1640 ~PatchingAssembler();
1644 DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS);
1645 DEFINE_REGISTER_NAMES(DoubleRegister, DOUBLE_REGISTERS);
1651 #endif // V8_PPC_ASSEMBLER_PPC_H_