Skip to content

Commit ea04731

Browse files
Junliang YanV8 LUCI CQ
authored andcommitted
[maglev] implement support for ppc64
Change-Id: I115896d8cec1506eda0807923b3bc6359ae6c3d3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6732140 Commit-Queue: Junliang Yan <[email protected]> Reviewed-by: Milad Farazmand <[email protected]> Reviewed-by: Victor Gomes <[email protected]> Cr-Commit-Position: refs/heads/main@{#101457}
1 parent 5ff0a6a commit ea04731

30 files changed

Lines changed: 3966 additions & 166 deletions

BUILD.gn

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4485,6 +4485,8 @@ v8_header_set("v8_internal_headers") {
44854485
sources += [ "src/maglev/x64/maglev-assembler-x64-inl.h" ]
44864486
} else if (v8_current_cpu == "s390x") {
44874487
sources += [ "src/maglev/s390/maglev-assembler-s390-inl.h" ]
4488+
} else if (v8_current_cpu == "ppc64") {
4489+
sources += [ "src/maglev/ppc64/maglev-assembler-ppc64-inl.h" ]
44884490
}
44894491
}
44904492

@@ -5996,6 +5998,11 @@ v8_source_set("v8_base_without_compiler") {
59965998
"src/maglev/s390/maglev-assembler-s390.cc",
59975999
"src/maglev/s390/maglev-ir-s390.cc",
59986000
]
6001+
} else if (v8_current_cpu == "ppc64") {
6002+
sources += [
6003+
"src/maglev/ppc64/maglev-assembler-ppc64.cc",
6004+
"src/maglev/ppc64/maglev-ir-ppc64.cc",
6005+
]
59996006
}
60006007
}
60016008

src/builtins/ppc/builtins-ppc.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3003,6 +3003,31 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
30033003
__ TailCallBuiltin(Builtin::kConstructedNonConstructable);
30043004
}
30053005

3006+
#ifdef V8_ENABLE_MAGLEV
3007+
3008+
void Builtins::Generate_MaglevFunctionEntryStackCheck(MacroAssembler* masm,
3009+
bool save_new_target) {
3010+
// Input (r0): Stack size (Smi).
3011+
// This builtin can be invoked just after Maglev's prologue.
3012+
// All registers are available, except (possibly) new.target.
3013+
ASM_CODE_COMMENT(masm);
3014+
{
3015+
FrameScope scope(masm, StackFrame::INTERNAL);
3016+
__ AssertSmi(r3);
3017+
if (save_new_target) {
3018+
__ Push(kJavaScriptCallNewTargetRegister);
3019+
}
3020+
__ Push(r3);
3021+
__ CallRuntime(Runtime::kStackGuardWithGap, 1);
3022+
if (save_new_target) {
3023+
__ Pop(kJavaScriptCallNewTargetRegister);
3024+
}
3025+
}
3026+
__ Ret();
3027+
}
3028+
3029+
#endif // V8_ENABLE_MAGLEV
3030+
30063031
#if V8_ENABLE_WEBASSEMBLY
30073032

30083033
struct SaveWasmParamsScope {

src/codegen/ppc/assembler-ppc.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ void Assembler::PatchInHeapNumberRequest(Address pc,
206206
Assembler::Assembler(const AssemblerOptions& options,
207207
std::unique_ptr<AssemblerBuffer> buffer)
208208
: AssemblerBase(options, std::move(buffer)),
209-
scratch_register_list_({ip}),
209+
scratch_register_list_(DefaultTmpList()),
210+
scratch_double_register_list_(DefaultFPTmpList()),
210211
constant_pool_builder_(kLoadPtrMaxReachBits, kLoadDoubleMaxReachBits) {
211212
reloc_info_writer.Reposition(buffer_start_ + buffer_->size(), pc_);
212213

@@ -2195,6 +2196,11 @@ PatchingAssembler::~PatchingAssembler() {
21952196
DCHECK_EQ(reloc_info_writer.pos(), buffer_start_ + buffer_->size());
21962197
}
21972198

2199+
RegList Assembler::DefaultTmpList() { return {r26, ip}; }
2200+
DoubleRegList Assembler::DefaultFPTmpList() {
2201+
return {kScratchDoubleReg, kDoubleRegZero};
2202+
}
2203+
21982204
} // namespace internal
21992205
} // namespace v8
22002206

src/codegen/ppc/assembler-ppc.h

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ class Assembler : public AssemblerBase {
208208
}
209209
}
210210

211+
static RegList DefaultTmpList();
212+
static DoubleRegList DefaultFPTmpList();
213+
211214
// Label operations & relative jumps (PPUM Appendix D)
212215
//
213216
// Takes a branch opcode (cc) and a label (L) and generates
@@ -379,6 +382,8 @@ class Assembler : public AssemblerBase {
379382
inline void name(const Register dst, const MemOperand& src) { \
380383
x_form(instr_name, src.ra(), dst, src.rb(), SetEH); \
381384
}
385+
#define DECLARE_PPC_X_INSTRUCTIONS_EH_U_FORM(name, instr_name, instr_value) \
386+
inline void name(const CRegister cr) { x_form(instr_name, cr); }
382387

383388
inline void x_form(Instr instr, int f1, int f2, int f3, int rc) {
384389
emit(instr | f1 * B21 | f2 * B16 | f3 * B11 | rc);
@@ -397,6 +402,9 @@ class Assembler : public AssemblerBase {
397402
emit(instr | cr.code() * B23 | L * B21 | s1.code() * B16 | s2.code() * B11 |
398403
rc);
399404
}
405+
inline void x_form(Instr instr, CRegister cr) {
406+
emit(instr | cr.code() * B23);
407+
}
400408

401409
PPC_X_OPCODE_A_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_A_FORM)
402410
PPC_X_OPCODE_B_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_B_FORM)
@@ -407,6 +415,7 @@ class Assembler : public AssemblerBase {
407415
PPC_X_OPCODE_G_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_G_FORM)
408416
PPC_X_OPCODE_EH_S_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_EH_S_FORM)
409417
PPC_X_OPCODE_EH_L_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_EH_L_FORM)
418+
PPC_X_OPCODE_EH_U_FORM_LIST(DECLARE_PPC_X_INSTRUCTIONS_EH_U_FORM)
410419

411420
inline void notx(Register dst, Register src, RCBit rc = LeaveRC) {
412421
nor(dst, src, src, rc);
@@ -628,6 +637,10 @@ class Assembler : public AssemblerBase {
628637
#undef DECLARE_PPC_PREFIX_INSTRUCTIONS_TYPE_10
629638

630639
RegList* GetScratchRegisterList() { return &scratch_register_list_; }
640+
DoubleRegList* GetScratchDoubleRegisterList() {
641+
return &scratch_double_register_list_;
642+
}
643+
631644
// ---------------------------------------------------------------------------
632645
// InstructionStream generation
633646

@@ -731,6 +744,12 @@ class Assembler : public AssemblerBase {
731744
case nooverflow:
732745
bc(b_offset, BF, encode_crbit(cr, CR_SO), lk);
733746
break;
747+
case overflow32:
748+
bc(b_offset, BT, encode_crbit(cr, CR_OV32), lk);
749+
break;
750+
case nooverflow32:
751+
bc(b_offset, BF, encode_crbit(cr, CR_OV32), lk);
752+
break;
734753
default:
735754
UNIMPLEMENTED();
736755
}
@@ -773,6 +792,12 @@ class Assembler : public AssemblerBase {
773792
case nooverflow:
774793
bclr(BF, encode_crbit(cr, CR_SO), lk);
775794
break;
795+
case overflow32:
796+
bclr(BT, encode_crbit(cr, CR_OV32), lk);
797+
break;
798+
case nooverflow32:
799+
bclr(BF, encode_crbit(cr, CR_OV32), lk);
800+
break;
776801
default:
777802
UNIMPLEMENTED();
778803
}
@@ -817,6 +842,12 @@ class Assembler : public AssemblerBase {
817842
case nooverflow:
818843
isel(rt, rb, ra, encode_crbit(cr, CR_SO));
819844
break;
845+
case overflow32:
846+
isel(rt, ra, rb, encode_crbit(cr, CR_OV32));
847+
break;
848+
case nooverflow32:
849+
isel(rt, rb, ra, encode_crbit(cr, CR_OV32));
850+
break;
820851
default:
821852
UNIMPLEMENTED();
822853
}
@@ -1405,6 +1436,7 @@ class Assembler : public AssemblerBase {
14051436

14061437
// Scratch registers available for use by the Assembler.
14071438
RegList scratch_register_list_;
1439+
DoubleRegList scratch_double_register_list_;
14081440

14091441
// The bound position, before this we cannot do instruction elimination.
14101442
int last_bound_pos_;
@@ -1549,27 +1581,65 @@ class V8_EXPORT_PRIVATE V8_NODISCARD UseScratchRegisterScope {
15491581
public:
15501582
explicit UseScratchRegisterScope(Assembler* assembler)
15511583
: assembler_(assembler),
1552-
old_available_(*assembler->GetScratchRegisterList()) {}
1584+
old_available_(*assembler->GetScratchRegisterList()),
1585+
old_available_double_(*assembler->GetScratchDoubleRegisterList()) {}
15531586

15541587
~UseScratchRegisterScope() {
15551588
*assembler_->GetScratchRegisterList() = old_available_;
1589+
*assembler_->GetScratchDoubleRegisterList() = old_available_double_;
15561590
}
15571591

15581592
Register Acquire() {
15591593
return assembler_->GetScratchRegisterList()->PopFirst();
15601594
}
15611595

1596+
DoubleRegister AcquireDouble() {
1597+
return assembler_->GetScratchDoubleRegisterList()->PopFirst();
1598+
}
1599+
15621600
// Check if we have registers available to acquire.
15631601
bool CanAcquire() const {
15641602
return !assembler_->GetScratchRegisterList()->is_empty();
15651603
}
15661604

1605+
void Include(const Register& reg1, const Register& reg2 = no_reg) {
1606+
RegList* available = assembler_->GetScratchRegisterList();
1607+
DCHECK_NOT_NULL(available);
1608+
DCHECK(!available->has(reg1));
1609+
DCHECK(!available->has(reg2));
1610+
available->set(reg1);
1611+
available->set(reg2);
1612+
}
1613+
void Include(RegList list) {
1614+
RegList* available = assembler_->GetScratchRegisterList();
1615+
DCHECK_NOT_NULL(available);
1616+
*available = *available | list;
1617+
}
1618+
void Include(DoubleRegList list) {
1619+
DoubleRegList* available = assembler_->GetScratchDoubleRegisterList();
1620+
DCHECK_NOT_NULL(available);
1621+
DCHECK_EQ((*available & list).bits(), 0x0);
1622+
*available = *available | list;
1623+
}
1624+
1625+
DoubleRegList AvailableDoubleRegList() {
1626+
return *assembler_->GetScratchDoubleRegisterList();
1627+
}
1628+
void SetAvailableDoubleRegList(DoubleRegList available) {
1629+
*assembler_->GetScratchDoubleRegisterList() = available;
1630+
}
1631+
RegList Available() { return *assembler_->GetScratchRegisterList(); }
1632+
void SetAvailable(RegList available) {
1633+
*assembler_->GetScratchRegisterList() = available;
1634+
}
1635+
15671636
private:
15681637
friend class Assembler;
15691638
friend class MacroAssembler;
15701639

15711640
Assembler* assembler_;
15721641
RegList old_available_;
1642+
DoubleRegList old_available_double_;
15731643
};
15741644

15751645
} // namespace internal

src/codegen/ppc/constants-ppc.h

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ enum Condition : int {
128128
overflow = 8, // Summary overflow
129129
nooverflow = 9,
130130
al = 10, // Always.
131+
overflow32 = 11,
132+
nooverflow32 = 12,
131133

132134
// Unified cross-platform condition names/aliases.
133135
// Do not set unsigned constants equal to their signed variants.
@@ -139,14 +141,16 @@ enum Condition : int {
139141
kGreaterThan = gt,
140142
kLessThanEqual = le,
141143
kGreaterThanEqual = ge,
142-
kUnsignedLessThan = 11,
143-
kUnsignedGreaterThan = 12,
144-
kUnsignedLessThanEqual = 13,
145-
kUnsignedGreaterThanEqual = 14,
144+
kUnsignedLessThan = 13,
145+
kUnsignedGreaterThan = 14,
146+
kUnsignedLessThanEqual = 15,
147+
kUnsignedGreaterThanEqual = 16,
146148
kOverflow = overflow,
147149
kNoOverflow = nooverflow,
148-
kZero = 15,
149-
kNotZero = 16,
150+
kZero = 17,
151+
kNotZero = 18,
152+
kOverflow32 = overflow32,
153+
kNoOverflow32 = nooverflow32,
150154
};
151155

152156
inline Condition to_condition(Condition cond) {
@@ -181,6 +185,8 @@ inline bool is_signed(Condition cond) {
181185
case kNoOverflow:
182186
case kZero:
183187
case kNotZero:
188+
case kOverflow32:
189+
case kNoOverflow32:
184190
return true;
185191

186192
case kUnsignedLessThan:
@@ -194,9 +200,49 @@ inline bool is_signed(Condition cond) {
194200
}
195201
}
196202

197-
inline Condition NegateCondition(Condition cond) {
203+
constexpr inline Condition NegateCondition(Condition cond) {
198204
DCHECK(cond != al);
199-
return static_cast<Condition>(cond ^ ne);
205+
switch (cond) {
206+
case eq:
207+
return ne;
208+
case ne:
209+
return eq;
210+
case ge:
211+
return lt;
212+
case gt:
213+
return le;
214+
case le:
215+
return gt;
216+
case lt:
217+
return ge;
218+
case kOverflow:
219+
return kNoOverflow;
220+
case kNoOverflow:
221+
return kOverflow;
222+
case unordered:
223+
return ordered;
224+
case ordered:
225+
return unordered;
226+
case kUnsignedLessThan:
227+
return kUnsignedGreaterThanEqual;
228+
case kUnsignedGreaterThan:
229+
return kUnsignedLessThanEqual;
230+
case kUnsignedLessThanEqual:
231+
return kUnsignedGreaterThan;
232+
case kUnsignedGreaterThanEqual:
233+
return kUnsignedLessThan;
234+
case kZero:
235+
return kNotZero;
236+
case kNotZero:
237+
return kZero;
238+
case kOverflow32:
239+
return kNoOverflow32;
240+
case kNoOverflow32:
241+
return kOverflow32;
242+
default:
243+
DCHECK(false);
244+
}
245+
return al;
200246
}
201247

202248
// -----------------------------------------------------------------------------
@@ -1378,6 +1424,11 @@ using Instr = uint32_t;
13781424
/* Load Doubleword And Reserve Indexed */ \
13791425
V(ldarx, LDARX, 0x7C0000A8)
13801426

1427+
#define PPC_X_OPCODE_EH_U_FORM_LIST(V) \
1428+
/* Move to CR from XER Extended X-form */ \
1429+
V(mcrxrx, MCRXRX, 0x7C000480) \
1430+
V(mcrxr, MCRXR, 0x7C000400)
1431+
13811432
#define PPC_X_OPCODE_UNUSED_LIST(V) \
13821433
/* Bit Permute Doubleword */ \
13831434
V(bpermd, BPERMD, 0x7C0001F8) \
@@ -1515,8 +1566,6 @@ using Instr = uint32_t;
15151566
V(dcbi, DCBI, 0x7C0003AC) \
15161567
/* Instruction Cache Block Touch */ \
15171568
V(icbt, ICBT, 0x7C00002C) \
1518-
/* Move to Condition Register from XER */ \
1519-
V(mcrxr, MCRXR, 0x7C000400) \
15201569
/* TLB Invalidate Local Indexed */ \
15211570
V(tlbilx, TLBILX, 0x7C000024) \
15221571
/* TLB Invalidate Virtual Address Indexed */ \
@@ -1830,6 +1879,7 @@ using Instr = uint32_t;
18301879
PPC_X_OPCODE_F_FORM_LIST(V) \
18311880
PPC_X_OPCODE_G_FORM_LIST(V) \
18321881
PPC_X_OPCODE_EH_L_FORM_LIST(V) \
1882+
PPC_X_OPCODE_EH_U_FORM_LIST(V) \
18331883
PPC_X_OPCODE_UNUSED_LIST(V)
18341884

18351885
#define PPC_EVS_OPCODE_LIST(V) \
@@ -2904,7 +2954,18 @@ enum BOfield { // Bits 25-21
29042954
#undef CR_SO
29052955
#endif
29062956

2907-
enum CRBit { CR_LT = 0, CR_GT = 1, CR_EQ = 2, CR_SO = 3, CR_FU = 3 };
2957+
enum CRBit {
2958+
CR_LT = 0,
2959+
CR_GT = 1,
2960+
CR_EQ = 2,
2961+
CR_SO = 3,
2962+
CR_FU = 3,
2963+
// for MCRXRX
2964+
CR_OV = 0,
2965+
CR_OV32 = 1,
2966+
CR_CA = 2,
2967+
CR_CA32 = 3
2968+
};
29082969

29092970
#define CRWIDTH 4
29102971

0 commit comments

Comments
 (0)