mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:16:51 +00:00
Don't touch x18 on ARM64 - it is globally reserved on iOS.
Move SP on ARM64 to x19. Use a mask instead of a range for determining the globally blocked registers. R=regis@google.com Review URL: https://codereview.chromium.org/1417433002 .
This commit is contained in:
parent
caedcce440
commit
91bc8005fe
|
@ -26,8 +26,6 @@ namespace dart {
|
|||
|
||||
|
||||
enum Register {
|
||||
kNoRegister = -1,
|
||||
kFirstFreeCpuRegister = 0,
|
||||
R0 = 0,
|
||||
R1 = 1,
|
||||
R2 = 2,
|
||||
|
@ -36,21 +34,23 @@ enum Register {
|
|||
R5 = 5,
|
||||
R6 = 6,
|
||||
R7 = 7,
|
||||
R8 = 8,
|
||||
R9 = 9,
|
||||
R10 = 10,
|
||||
R11 = 11,
|
||||
R12 = 12,
|
||||
R13 = 13,
|
||||
R14 = 14,
|
||||
kLastFreeCpuRegister = 14,
|
||||
R15 = 15,
|
||||
R8 = 8, // THR
|
||||
R9 = 9, // PP
|
||||
R10 = 10, // CTX
|
||||
R11 = 11, // FP
|
||||
R12 = 12, // IP aka TMP
|
||||
R13 = 13, // SP
|
||||
R14 = 14, // LR
|
||||
R15 = 15, // PC
|
||||
kNumberOfCpuRegisters = 16,
|
||||
kNoRegister = -1, // Signals an illegal register.
|
||||
|
||||
// Aliases.
|
||||
FP = R11,
|
||||
IP = R12,
|
||||
SP = R13,
|
||||
LR = R14,
|
||||
PC = R15,
|
||||
kNumberOfCpuRegisters = 16,
|
||||
};
|
||||
|
||||
|
||||
|
@ -269,12 +269,16 @@ const QRegister kAbiFirstPreservedFpuReg = Q4;
|
|||
const QRegister kAbiLastPreservedFpuReg = Q7;
|
||||
const int kAbiPreservedFpuRegCount = 4;
|
||||
|
||||
const RegList kReservedCpuRegisters =
|
||||
(1 << SPREG) |
|
||||
(1 << FPREG) |
|
||||
(1 << TMP) |
|
||||
(1 << PP) |
|
||||
(1 << THR) |
|
||||
(1 << PC);
|
||||
// CPU registers available to Dart allocator.
|
||||
const RegList kDartAvailableCpuRegs =
|
||||
(1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
|
||||
(1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) |
|
||||
(1 << R8) | (1 << R14);
|
||||
|
||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
||||
// Registers available to Dart that are not preserved by runtime calls.
|
||||
const RegList kDartVolatileCpuRegs =
|
||||
kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
namespace dart {
|
||||
|
||||
enum Register {
|
||||
kFirstFreeCpuRegister = 0,
|
||||
R0 = 0,
|
||||
R1 = 1,
|
||||
R2 = 2,
|
||||
|
@ -29,16 +28,15 @@ enum Register {
|
|||
R15 = 15,
|
||||
R16 = 16, // IP0 aka TMP
|
||||
R17 = 17, // IP1 aka TMP2
|
||||
R18 = 18, // SP in Dart code.
|
||||
R19 = 19,
|
||||
R20 = 20,
|
||||
R18 = 18, // "platform register" on iOS.
|
||||
R19 = 19, // SP in Dart code.
|
||||
R20 = 20, // THR
|
||||
R21 = 21,
|
||||
R22 = 22,
|
||||
R23 = 23,
|
||||
R24 = 24,
|
||||
R25 = 25,
|
||||
R26 = 26,
|
||||
kLastFreeCpuRegister = 26,
|
||||
R27 = 27, // PP
|
||||
R28 = 28, // CTX
|
||||
R29 = 29, // FP
|
||||
|
@ -55,11 +53,12 @@ enum Register {
|
|||
// Aliases.
|
||||
IP0 = R16,
|
||||
IP1 = R17,
|
||||
SP = R18,
|
||||
SP = R19,
|
||||
FP = R29,
|
||||
LR = R30,
|
||||
};
|
||||
|
||||
|
||||
enum VRegister {
|
||||
V0 = 0,
|
||||
V1 = 1,
|
||||
|
@ -113,12 +112,13 @@ const Register CTX = R28; // Location of current context at method entry.
|
|||
const Register PP = R27; // Caches object pool pointer in generated code.
|
||||
const Register CODE_REG = R24;
|
||||
const Register FPREG = FP; // Frame pointer register.
|
||||
const Register SPREG = R18; // Stack pointer register.
|
||||
const Register SPREG = R19; // Stack pointer register.
|
||||
const Register LRREG = LR; // Link register.
|
||||
const Register ICREG = R5; // IC data register.
|
||||
const Register ARGS_DESC_REG = R4; // Arguments descriptor register.
|
||||
const Register THR = R20; // Caches current thread in generated code.
|
||||
|
||||
|
||||
// Exception object is passed in this register to the catch handlers when an
|
||||
// exception is thrown.
|
||||
const Register kExceptionObjectReg = R0;
|
||||
|
@ -143,25 +143,31 @@ const RegList kAbiArgumentCpuRegs =
|
|||
(1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
|
||||
(1 << R4) | (1 << R5) | (1 << R6) | (1 << R7);
|
||||
const RegList kAbiPreservedCpuRegs =
|
||||
(1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) |
|
||||
(1 << R23) | (1 << R24) | (1 << R25) | (1 << R26) |
|
||||
(1 << R27) | (1 << R28);
|
||||
const Register kAbiFirstPreservedCpuReg = R19;
|
||||
(1 << R20) | (1 << R21) | (1 << R22) | (1 << R23) |
|
||||
(1 << R24) | (1 << R25) | (1 << R26) | (1 << R27) |
|
||||
(1 << R28);
|
||||
const Register kAbiFirstPreservedCpuReg = R20;
|
||||
const Register kAbiLastPreservedCpuReg = R28;
|
||||
const int kAbiPreservedCpuRegCount = 10;
|
||||
const int kAbiPreservedCpuRegCount = 9;
|
||||
const VRegister kAbiFirstPreservedFpuReg = V8;
|
||||
const VRegister kAbiLastPreservedFpuReg = V15;
|
||||
const int kAbiPreservedFpuRegCount = 8;
|
||||
|
||||
const intptr_t kReservedCpuRegisters =
|
||||
(1 << SPREG) | // Dart SP
|
||||
(1 << FPREG) |
|
||||
(1 << TMP) |
|
||||
(1 << TMP2) |
|
||||
(1 << PP) |
|
||||
(1 << THR) |
|
||||
(1 << LR) |
|
||||
(1 << R31) | // C++ SP
|
||||
(1 << CTX) |
|
||||
(1 << R18); // iOS platform register.
|
||||
// TODO(rmacnak): Only reserve on Mac & iOS.
|
||||
// CPU registers available to Dart allocator.
|
||||
const RegList kDartAvailableCpuRegs =
|
||||
(1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
|
||||
(1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) |
|
||||
(1 << R8) | (1 << R9) | (1 << R10) | (1 << R11) |
|
||||
(1 << R12) | (1 << R13) | (1 << R14) | (1 << R15) |
|
||||
(1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) |
|
||||
(1 << R23) | (1 << R24) | (1 << R25) | (1 << R26);
|
||||
|
||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
||||
// Registers available to Dart that are not preserved by runtime calls.
|
||||
const RegList kDartVolatileCpuRegs =
|
||||
kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
namespace dart {
|
||||
|
||||
enum Register {
|
||||
kFirstFreeCpuRegister = 0,
|
||||
EAX = 0,
|
||||
ECX = 1,
|
||||
EDX = 2,
|
||||
|
@ -19,9 +18,8 @@ enum Register {
|
|||
EBP = 5,
|
||||
ESI = 6,
|
||||
EDI = 7,
|
||||
kLastFreeCpuRegister = 7,
|
||||
kNumberOfCpuRegisters = 8,
|
||||
kNoRegister = -1 // Signals an illegal register.
|
||||
kNoRegister = -1, // Signals an illegal register.
|
||||
};
|
||||
|
||||
|
||||
|
@ -71,6 +69,7 @@ const Register ICREG = ECX; // IC data register.
|
|||
const Register ARGS_DESC_REG = EDX; // Arguments descriptor register.
|
||||
const Register THR = ESI; // Caches current thread in generated code.
|
||||
|
||||
|
||||
// Exception object is passed in this register to the catch handlers when an
|
||||
// exception is thrown.
|
||||
const Register kExceptionObjectReg = EAX;
|
||||
|
@ -80,6 +79,18 @@ const Register kExceptionObjectReg = EAX;
|
|||
const Register kStackTraceObjectReg = EDX;
|
||||
|
||||
|
||||
typedef uint32_t RegList;
|
||||
const RegList kAllCpuRegistersList = 0xFF;
|
||||
|
||||
const intptr_t kReservedCpuRegisters =
|
||||
(1 << SPREG) |
|
||||
(1 << FPREG) |
|
||||
(1 << THR);
|
||||
// CPU registers available to Dart allocator.
|
||||
const RegList kDartAvailableCpuRegs =
|
||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
||||
|
||||
|
||||
enum ScaleFactor {
|
||||
TIMES_1 = 0,
|
||||
TIMES_2 = 1,
|
||||
|
|
|
@ -11,8 +11,7 @@ namespace dart {
|
|||
|
||||
enum Register {
|
||||
R0 = 0,
|
||||
R1 = 1,
|
||||
kFirstFreeCpuRegister = 2,
|
||||
R1 = 1, // AT aka TMP
|
||||
R2 = 2,
|
||||
R3 = 3,
|
||||
R4 = 4,
|
||||
|
@ -30,23 +29,23 @@ enum Register {
|
|||
R16 = 16,
|
||||
R17 = 17,
|
||||
R18 = 18,
|
||||
R19 = 19,
|
||||
R19 = 19, // THR
|
||||
R20 = 20,
|
||||
R21 = 21,
|
||||
kLastFreeCpuRegister = 21,
|
||||
R22 = 22,
|
||||
R23 = 23,
|
||||
R22 = 22, // CTX
|
||||
R23 = 23, // PP
|
||||
R24 = 24,
|
||||
R25 = 25,
|
||||
R26 = 26,
|
||||
R27 = 27,
|
||||
R28 = 28,
|
||||
R29 = 29,
|
||||
R30 = 30,
|
||||
R31 = 31,
|
||||
R29 = 29, // SP
|
||||
R30 = 30, // FP
|
||||
R31 = 31, // RA
|
||||
kNumberOfCpuRegisters = 32,
|
||||
IMM = 32, // Positive value is easier to encode than kNoRegister in bitfield.
|
||||
kNoRegister = -1,
|
||||
kNoRegister = -1, // Signals an illegal register.
|
||||
|
||||
|
||||
// Register aliases.
|
||||
ZR = R0,
|
||||
|
@ -188,6 +187,7 @@ const Register ICREG = S5; // IC data register.
|
|||
const Register ARGS_DESC_REG = S4;
|
||||
const Register THR = S3; // Caches current thread in generated code.
|
||||
|
||||
|
||||
// The code that generates a comparison can be far away from the code that
|
||||
// generates the branch that uses the result of that comparison. In this case,
|
||||
// CMPRES1 and CMPRES2 are used for the results of the comparison. We need two
|
||||
|
@ -207,7 +207,6 @@ const Register kStackTraceObjectReg = V1;
|
|||
typedef uint32_t RegList;
|
||||
const RegList kAllCpuRegistersList = 0xFFFFFFFF;
|
||||
|
||||
|
||||
const RegList kAbiArgumentCpuRegs =
|
||||
(1 << A0) | (1 << A1) | (1 << A2) | (1 << A3);
|
||||
const RegList kAbiPreservedCpuRegs =
|
||||
|
@ -221,13 +220,24 @@ const FRegister kAbiLastPreservedFpuReg =
|
|||
static_cast<FRegister>(kNumberOfFRegisters - 1);
|
||||
const int kAbiPreservedFpuRegCount = 12;
|
||||
|
||||
const RegList kReservedCpuRegisters =
|
||||
(1 << SPREG) |
|
||||
(1 << FPREG) |
|
||||
(1 << TMP) |
|
||||
(1 << PP) |
|
||||
(1 << THR) |
|
||||
(1 << CTX) |
|
||||
(1 << ZR) |
|
||||
(1 << CMPRES1) |
|
||||
(1 << CMPRES2) |
|
||||
(1 << K0) |
|
||||
(1 << K1) |
|
||||
(1 << GP) |
|
||||
(1 << RA);
|
||||
// CPU registers available to Dart allocator.
|
||||
const RegList kDartAvailableCpuRegs =
|
||||
(1 << R2) | (1 << R3) | (1 << R4) | (1 << R5) |
|
||||
(1 << R6) | (1 << R7) | (1 << R8) | (1 << R9) |
|
||||
(1 << R10) | (1 << R11) | (1 << R12) | (1 << R13) |
|
||||
(1 << R14) | (1 << R15) | (1 << R16) | (1 << R17) |
|
||||
(1 << R18) | (1 << R19) | (1 << R20) | (1 << R21);
|
||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
||||
// Registers available to Dart that are not preserved by runtime calls.
|
||||
const RegList kDartVolatileCpuRegs =
|
||||
kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
|
||||
const int kDartVolatileCpuRegCount = 14;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
namespace dart {
|
||||
|
||||
enum Register {
|
||||
kFirstFreeCpuRegister = 0,
|
||||
RAX = 0,
|
||||
RCX = 1,
|
||||
RDX = 2,
|
||||
|
@ -25,9 +24,8 @@ enum Register {
|
|||
R13 = 13,
|
||||
R14 = 14,
|
||||
R15 = 15,
|
||||
kLastFreeCpuRegister = 15,
|
||||
kNumberOfCpuRegisters = 16,
|
||||
kNoRegister = -1 // Signals an illegal register.
|
||||
kNoRegister = -1, // Signals an illegal register.
|
||||
};
|
||||
|
||||
|
||||
|
@ -96,6 +94,7 @@ const Register ARGS_DESC_REG = R10; // Arguments descriptor register.
|
|||
const Register CODE_REG = R12;
|
||||
const Register THR = R14; // Caches current thread in generated code.
|
||||
|
||||
|
||||
// Exception object is passed in this register to the catch handlers when an
|
||||
// exception is thrown.
|
||||
const Register kExceptionObjectReg = RAX;
|
||||
|
@ -105,6 +104,20 @@ const Register kExceptionObjectReg = RAX;
|
|||
const Register kStackTraceObjectReg = RDX;
|
||||
|
||||
|
||||
typedef uint32_t RegList;
|
||||
const RegList kAllCpuRegistersList = 0xFFFF;
|
||||
|
||||
const RegList kReservedCpuRegisters =
|
||||
(1 << SPREG) |
|
||||
(1 << FPREG) |
|
||||
(1 << TMP) |
|
||||
(1 << PP) |
|
||||
(1 << THR);
|
||||
// CPU registers available to Dart allocator.
|
||||
const RegList kDartAvailableCpuRegs =
|
||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
||||
|
||||
|
||||
enum ScaleFactor {
|
||||
TIMES_1 = 0,
|
||||
TIMES_2 = 1,
|
||||
|
|
|
@ -83,12 +83,12 @@ void ARM64Decoder::Print(const char* str) {
|
|||
|
||||
|
||||
// These register names are defined in a way to match the native disassembler
|
||||
// formatting, except for register aliases ctx (r9) and pp (r10).
|
||||
// formatting, except for register aliases ctx (r9), pp (r10) and sp (r19).
|
||||
// See for example the command "objdump -d <binary file>".
|
||||
static const char* reg_names[kNumberOfCpuRegisters] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
"ip0", "ip1", "sp", "r19", "r20", "r21", "r22", "r23",
|
||||
"ip0", "ip1", "r18", "sp", "r20", "r21", "r22", "r23",
|
||||
"r24", "r25", "r26", "pp", "ctx", "fp", "lr", "r31",
|
||||
};
|
||||
|
||||
|
|
|
@ -101,24 +101,11 @@ FlowGraphAllocator::FlowGraphAllocator(const FlowGraph& flow_graph,
|
|||
|
||||
// All registers are marked as "not blocked" (array initialized to false).
|
||||
// Mark the unavailable ones as "blocked" (true).
|
||||
for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) {
|
||||
blocked_cpu_registers_[i] = true;
|
||||
for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
|
||||
if ((kDartAvailableCpuRegs & (1 << i)) == 0) {
|
||||
blocked_cpu_registers_[i] = true;
|
||||
}
|
||||
}
|
||||
for (intptr_t i = kLastFreeCpuRegister + 1; i < kNumberOfCpuRegisters; i++) {
|
||||
blocked_cpu_registers_[i] = true;
|
||||
}
|
||||
if (TMP != kNoRegister) {
|
||||
blocked_cpu_registers_[TMP] = true;
|
||||
}
|
||||
if (TMP2 != kNoRegister) {
|
||||
blocked_cpu_registers_[TMP2] = true;
|
||||
}
|
||||
if (PP != kNoRegister) {
|
||||
blocked_cpu_registers_[PP] = true;
|
||||
}
|
||||
blocked_cpu_registers_[SPREG] = true;
|
||||
blocked_cpu_registers_[FPREG] = true;
|
||||
blocked_cpu_registers_[THR] = true;
|
||||
|
||||
// FpuTMP is used as scratch by optimized code and parallel move resolver.
|
||||
blocked_fpu_registers_[FpuTMP] = true;
|
||||
|
|
|
@ -1260,16 +1260,6 @@ static uword RegMaskBit(Register reg) {
|
|||
}
|
||||
|
||||
|
||||
// Mask of globally reserved registers. Some other registers are only reserved
|
||||
// in particular code (e.g., ARGS_DESC_REG in intrinsics).
|
||||
static const uword kReservedCpuRegisters = RegMaskBit(SPREG)
|
||||
| RegMaskBit(FPREG)
|
||||
| RegMaskBit(TMP)
|
||||
| RegMaskBit(TMP2)
|
||||
| RegMaskBit(PP)
|
||||
| RegMaskBit(THR);
|
||||
|
||||
|
||||
void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) {
|
||||
ASSERT(!is_optimizing());
|
||||
|
||||
|
@ -1279,16 +1269,10 @@ void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) {
|
|||
|
||||
bool blocked_registers[kNumberOfCpuRegisters];
|
||||
|
||||
// Mark all available registers free.
|
||||
// Block all registers globally reserved by the assembler, etc and mark
|
||||
// the rest as free.
|
||||
for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
|
||||
blocked_registers[i] = false;
|
||||
}
|
||||
|
||||
// Block all registers globally reserved by the assembler, etc.
|
||||
for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
|
||||
if ((kReservedCpuRegisters & (1 << i)) != 0) {
|
||||
blocked_registers[i] = true;
|
||||
}
|
||||
blocked_registers[i] = (kDartAvailableCpuRegs & (1 << i)) == 0;
|
||||
}
|
||||
|
||||
// Mark all fixed input, temp and output registers as used.
|
||||
|
@ -1316,14 +1300,6 @@ void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) {
|
|||
blocked_registers[locs->out(0).reg()] = true;
|
||||
}
|
||||
|
||||
// Block all non-free registers.
|
||||
for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) {
|
||||
blocked_registers[i] = true;
|
||||
}
|
||||
for (intptr_t i = kLastFreeCpuRegister + 1; i < kNumberOfCpuRegisters; i++) {
|
||||
blocked_registers[i] = true;
|
||||
}
|
||||
|
||||
// Allocate all unallocated input locations.
|
||||
const bool should_pop = !instr->IsPushArgument() && !instr->IsPushTemp();
|
||||
for (intptr_t i = locs->input_count() - 1; i >= 0; i--) {
|
||||
|
@ -1582,8 +1558,8 @@ ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope(
|
|||
reg_ = static_cast<Register>(
|
||||
resolver_->AllocateScratchRegister(Location::kRegister,
|
||||
blocked_mask,
|
||||
kFirstFreeCpuRegister,
|
||||
kLastFreeCpuRegister,
|
||||
0,
|
||||
kNumberOfCpuRegisters - 1,
|
||||
&spilled_));
|
||||
|
||||
if (spilled_) {
|
||||
|
|
|
@ -900,6 +900,7 @@ void Simulator::set_register(
|
|||
Instr* instr, Register reg, int64_t value, R31Type r31t) {
|
||||
// Register is in range.
|
||||
ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
|
||||
ASSERT(instr == NULL || reg != R18); // R18 is globally reserved on iOS.
|
||||
if ((reg != R31) || (r31t != R31IsZR)) {
|
||||
registers_[reg] = value;
|
||||
// If we're setting CSP, make sure it is 16-byte aligned. In truth, CSP
|
||||
|
@ -1650,24 +1651,24 @@ void Simulator::DoRedirectedCall(Instr* instr) {
|
|||
|
||||
// Zap caller-saved registers, since the actual runtime call could have
|
||||
// used them.
|
||||
set_register(instr, R2, icount_);
|
||||
set_register(instr, R3, icount_);
|
||||
set_register(instr, R4, icount_);
|
||||
set_register(instr, R5, icount_);
|
||||
set_register(instr, R6, icount_);
|
||||
set_register(instr, R7, icount_);
|
||||
set_register(instr, R8, icount_);
|
||||
set_register(instr, R9, icount_);
|
||||
set_register(instr, R10, icount_);
|
||||
set_register(instr, R11, icount_);
|
||||
set_register(instr, R12, icount_);
|
||||
set_register(instr, R13, icount_);
|
||||
set_register(instr, R14, icount_);
|
||||
set_register(instr, R15, icount_);
|
||||
set_register(instr, IP0, icount_);
|
||||
set_register(instr, IP1, icount_);
|
||||
set_register(instr, R18, icount_);
|
||||
set_register(instr, LR, icount_);
|
||||
set_register(NULL, R2, icount_);
|
||||
set_register(NULL, R3, icount_);
|
||||
set_register(NULL, R4, icount_);
|
||||
set_register(NULL, R5, icount_);
|
||||
set_register(NULL, R6, icount_);
|
||||
set_register(NULL, R7, icount_);
|
||||
set_register(NULL, R8, icount_);
|
||||
set_register(NULL, R9, icount_);
|
||||
set_register(NULL, R10, icount_);
|
||||
set_register(NULL, R11, icount_);
|
||||
set_register(NULL, R12, icount_);
|
||||
set_register(NULL, R13, icount_);
|
||||
set_register(NULL, R14, icount_);
|
||||
set_register(NULL, R15, icount_);
|
||||
set_register(NULL, IP0, icount_);
|
||||
set_register(NULL, IP1, icount_);
|
||||
set_register(NULL, R18, icount_);
|
||||
set_register(NULL, LR, icount_);
|
||||
|
||||
// TODO(zra): Zap caller-saved fpu registers.
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ static const int kCallerSpSlotFromFp = 2;
|
|||
|
||||
// Entry and exit frame layout.
|
||||
static const int kExitLinkSlotFromEntryFp = -27;
|
||||
COMPILE_ASSERT(kAbiPreservedCpuRegCount == 7);
|
||||
COMPILE_ASSERT(kAbiPreservedFpuRegCount == 4);
|
||||
|
||||
} // namespace dart
|
||||
|
||||
|
|
|
@ -44,7 +44,9 @@ static const int kCallerSpSlotFromFp = 2;
|
|||
static const int kSavedAboveReturnAddress = 3; // Saved above return address.
|
||||
|
||||
// Entry and exit frame layout.
|
||||
static const int kExitLinkSlotFromEntryFp = -22;
|
||||
static const int kExitLinkSlotFromEntryFp = -21;
|
||||
COMPILE_ASSERT(kAbiPreservedCpuRegCount == 9);
|
||||
COMPILE_ASSERT(kAbiPreservedFpuRegCount == 8);
|
||||
|
||||
} // namespace dart
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ static const int kCallerSpSlotFromFp = 2;
|
|||
|
||||
// Entry and exit frame layout.
|
||||
static const int kExitLinkSlotFromEntryFp = -24;
|
||||
COMPILE_ASSERT(kAbiPreservedCpuRegCount == 8);
|
||||
COMPILE_ASSERT(kAbiPreservedFpuRegCount == 12);
|
||||
|
||||
} // namespace dart
|
||||
|
||||
|
|
|
@ -829,7 +829,7 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
|||
__ LoadFromOffset(R6, THR, Thread::top_exit_frame_info_offset());
|
||||
__ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
|
||||
// kExitLinkSlotFromEntryFp must be kept in sync with the code below.
|
||||
ASSERT(kExitLinkSlotFromEntryFp == -22);
|
||||
ASSERT(kExitLinkSlotFromEntryFp == -21);
|
||||
__ Push(R6);
|
||||
|
||||
// Load arguments descriptor array into R4, which is passed to Dart code.
|
||||
|
|
Loading…
Reference in a new issue