Ignore:
Timestamp:
Jul 21, 2017, 1:44:33 PM (8 years ago)
Author:
[email protected]
Message:

Refactor MASM probe CPUState to use arrays for register storage.
https://bugs.webkit.org/show_bug.cgi?id=174694

Reviewed by Keith Miller.

Using arrays for register storage in CPUState allows us to do away with the
huge switch statements to decode each register id. We can now simply index into
the arrays.

With this patch, we now:

  1. Remove the need for macros for defining the list of CPU registers. We can go back to simple enums. This makes the code easier to read.
  1. Make the assembler the authority on register names. Most of this code is moved into the assembler from GPRInfo and FPRInfo. GPRInfo and FPRInfo now forwards to the assembler.
  1. Make the assembler the authority on the number of registers of each type.
  1. Fix a "bug" in ARMv7's lastRegister(). It was previously omitting lr and pc. This is inconsistent with how every other CPU architecture implements lastRegister(). This patch fixes it to return the true last GPR i.e. pc, but updates RegisterSet::reservedHardwareRegisters() to exclude those registers.
  • assembler/ARM64Assembler.h:

(JSC::ARM64Assembler::numberOfRegisters):
(JSC::ARM64Assembler::firstSPRegister):
(JSC::ARM64Assembler::lastSPRegister):
(JSC::ARM64Assembler::numberOfSPRegisters):
(JSC::ARM64Assembler::numberOfFPRegisters):
(JSC::ARM64Assembler::gprName):
(JSC::ARM64Assembler::sprName):
(JSC::ARM64Assembler::fprName):

  • assembler/ARMAssembler.h:

(JSC::ARMAssembler::numberOfRegisters):
(JSC::ARMAssembler::firstSPRegister):
(JSC::ARMAssembler::lastSPRegister):
(JSC::ARMAssembler::numberOfSPRegisters):
(JSC::ARMAssembler::numberOfFPRegisters):
(JSC::ARMAssembler::gprName):
(JSC::ARMAssembler::sprName):
(JSC::ARMAssembler::fprName):

  • assembler/ARMv7Assembler.h:

(JSC::ARMv7Assembler::lastRegister):
(JSC::ARMv7Assembler::numberOfRegisters):
(JSC::ARMv7Assembler::firstSPRegister):
(JSC::ARMv7Assembler::lastSPRegister):
(JSC::ARMv7Assembler::numberOfSPRegisters):
(JSC::ARMv7Assembler::numberOfFPRegisters):
(JSC::ARMv7Assembler::gprName):
(JSC::ARMv7Assembler::sprName):
(JSC::ARMv7Assembler::fprName):

  • assembler/AbstractMacroAssembler.h:

(JSC::AbstractMacroAssembler::numberOfRegisters):
(JSC::AbstractMacroAssembler::gprName):
(JSC::AbstractMacroAssembler::firstSPRegister):
(JSC::AbstractMacroAssembler::lastSPRegister):
(JSC::AbstractMacroAssembler::numberOfSPRegisters):
(JSC::AbstractMacroAssembler::sprName):
(JSC::AbstractMacroAssembler::numberOfFPRegisters):
(JSC::AbstractMacroAssembler::fprName):

  • assembler/MIPSAssembler.h:

(JSC::MIPSAssembler::numberOfRegisters):
(JSC::MIPSAssembler::firstSPRegister):
(JSC::MIPSAssembler::lastSPRegister):
(JSC::MIPSAssembler::numberOfSPRegisters):
(JSC::MIPSAssembler::numberOfFPRegisters):
(JSC::MIPSAssembler::gprName):
(JSC::MIPSAssembler::sprName):
(JSC::MIPSAssembler::fprName):

  • assembler/MacroAssembler.h:

(JSC::MacroAssembler::CPUState::gprName):
(JSC::MacroAssembler::CPUState::sprName):
(JSC::MacroAssembler::CPUState::fprName):
(JSC::MacroAssembler::CPUState::gpr):
(JSC::MacroAssembler::CPUState::spr):
(JSC::MacroAssembler::CPUState::fpr):
(JSC::MacroAssembler::CPUState::pc):
(JSC::MacroAssembler::CPUState::fp):
(JSC::MacroAssembler::CPUState::sp):
(JSC::ProbeContext::gpr):
(JSC::ProbeContext::spr):
(JSC::ProbeContext::fpr):
(JSC::ProbeContext::gprName):
(JSC::ProbeContext::sprName):
(JSC::ProbeContext::fprName):
(JSC::MacroAssembler::numberOfRegisters): Deleted.
(JSC::MacroAssembler::numberOfFPRegisters): Deleted.

  • assembler/MacroAssemblerARM.cpp:
  • assembler/MacroAssemblerARM64.cpp:

(JSC::arm64ProbeTrampoline):

  • assembler/MacroAssemblerARMv7.cpp:
  • assembler/MacroAssemblerPrinter.cpp:

(JSC::Printer::nextID):
(JSC::Printer::printAllRegisters):
(JSC::Printer::printPCRegister):
(JSC::Printer::printRegisterID):
(JSC::Printer::printAddress):

  • assembler/MacroAssemblerX86Common.cpp:
  • assembler/X86Assembler.h:

(JSC::X86Assembler::numberOfRegisters):
(JSC::X86Assembler::firstSPRegister):
(JSC::X86Assembler::lastSPRegister):
(JSC::X86Assembler::numberOfSPRegisters):
(JSC::X86Assembler::numberOfFPRegisters):
(JSC::X86Assembler::gprName):
(JSC::X86Assembler::sprName):
(JSC::X86Assembler::fprName):

  • jit/FPRInfo.h:

(JSC::FPRInfo::debugName):

  • jit/GPRInfo.h:

(JSC::GPRInfo::debugName):

  • jit/RegisterSet.cpp:

(JSC::RegisterSet::reservedHardwareRegisters):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h

    r218782 r219740  
    158158namespace ARM64Registers {
    159159
    160 #define FOR_EACH_CPU_REGISTER(V) \
    161     FOR_EACH_CPU_GPREGISTER(V) \
    162     FOR_EACH_CPU_SPECIAL_REGISTER(V) \
    163     FOR_EACH_CPU_FPREGISTER(V)
    164 
    165 // The following are defined as pairs of the following value:
    166 // 1. type of the storage needed to save the register value by the JIT probe.
    167 // 2. name of the register.
    168 #define FOR_EACH_CPU_GPREGISTER(V) \
    169     /* Parameter/result registers */ \
    170     V(void*, x0) \
    171     V(void*, x1) \
    172     V(void*, x2) \
    173     V(void*, x3) \
    174     V(void*, x4) \
    175     V(void*, x5) \
    176     V(void*, x6) \
    177     V(void*, x7) \
    178     /* Indirect result location register */ \
    179     V(void*, x8) \
    180     /* Temporary registers */ \
    181     V(void*, x9) \
    182     V(void*, x10) \
    183     V(void*, x11) \
    184     V(void*, x12) \
    185     V(void*, x13) \
    186     V(void*, x14) \
    187     V(void*, x15) \
    188     /* Intra-procedure-call scratch registers (temporary) */ \
    189     V(void*, x16) \
    190     V(void*, x17) \
    191     /* Platform Register (temporary) */ \
    192     V(void*, x18) \
    193     /* Callee-saved */ \
    194     V(void*, x19) \
    195     V(void*, x20) \
    196     V(void*, x21) \
    197     V(void*, x22) \
    198     V(void*, x23) \
    199     V(void*, x24) \
    200     V(void*, x25) \
    201     V(void*, x26) \
    202     V(void*, x27) \
    203     V(void*, x28) \
    204     /* Special */ \
    205     V(void*, fp) \
    206     V(void*, lr) \
    207     V(void*, sp)
    208 
    209 #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
    210     V(void*, pc) \
    211     V(void*, nzcv) \
    212     V(void*, fpsr) \
    213 
    214 // ARM64 always has 32 FPU registers 128-bits each. See http://llvm.org/devmtg/2012-11/Northover-AArch64.pdf
    215 // and Section 5.1.2 in http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf.
    216 // However, we only use them for 64-bit doubles.
    217 #define FOR_EACH_CPU_FPREGISTER(V) \
    218     /* Parameter/result registers */ \
    219     V(double, q0) \
    220     V(double, q1) \
    221     V(double, q2) \
    222     V(double, q3) \
    223     V(double, q4) \
    224     V(double, q5) \
    225     V(double, q6) \
    226     V(double, q7) \
    227     /* Callee-saved (up to 64-bits only!) */ \
    228     V(double, q8) \
    229     V(double, q9) \
    230     V(double, q10) \
    231     V(double, q11) \
    232     V(double, q12) \
    233     V(double, q13) \
    234     V(double, q14) \
    235     V(double, q15) \
    236     /* Temporary registers */ \
    237     V(double, q16) \
    238     V(double, q17) \
    239     V(double, q18) \
    240     V(double, q19) \
    241     V(double, q20) \
    242     V(double, q21) \
    243     V(double, q22) \
    244     V(double, q23) \
    245     V(double, q24) \
    246     V(double, q25) \
    247     V(double, q26) \
    248     V(double, q27) \
    249     V(double, q28) \
    250     V(double, q29) \
    251     V(double, q30) \
    252     V(double, q31)
    253 
    254160typedef enum {
    255     #define DECLARE_REGISTER(_type, _regName) _regName,
    256     FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
    257     #undef DECLARE_REGISTER
     161    // Parameter/result registers.
     162    x0,
     163    x1,
     164    x2,
     165    x3,
     166    x4,
     167    x5,
     168    x6,
     169    x7,
     170    // Indirect result location register.
     171    x8,
     172    // Temporary registers.
     173    x9,
     174    x10,
     175    x11,
     176    x12,
     177    x13,
     178    x14,
     179    x15,
     180    // Intra-procedure-call scratch registers (temporary).
     181    x16,
     182    x17,
     183    // Platform Register (temporary).
     184    x18,
     185    // Callee-saved.
     186    x19,
     187    x20,
     188    x21,
     189    x22,
     190    x23,
     191    x24,
     192    x25,
     193    x26,
     194    x27,
     195    x28,
     196    // Special.
     197    fp,
     198    lr,
     199    sp,
    258200
    259201    ip0 = x16,
     
    265207
    266208typedef enum {
    267     #define DECLARE_REGISTER(_type, _regName) _regName,
    268     FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
    269     #undef DECLARE_REGISTER
     209    pc,
     210    nzcv,
     211    fpsr
     212} SPRegisterID;
     213
     214// ARM64 always has 32 FPU registers 128-bits each. See http://llvm.org/devmtg/2012-11/Northover-AArch64.pdf
     215// and Section 5.1.2 in http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf.
     216// However, we only use them for 64-bit doubles.
     217typedef enum {
     218    // Parameter/result registers.
     219    q0,
     220    q1,
     221    q2,
     222    q3,
     223    q4,
     224    q5,
     225    q6,
     226    q7,
     227    // Callee-saved (up to 64-bits only!).
     228    q8,
     229    q9,
     230    q10,
     231    q11,
     232    q12,
     233    q13,
     234    q14,
     235    q15,
     236    // Temporary registers.
     237    q16,
     238    q17,
     239    q18,
     240    q19,
     241    q20,
     242    q21,
     243    q22,
     244    q23,
     245    q24,
     246    q25,
     247    q26,
     248    q27,
     249    q28,
     250    q29,
     251    q30,
     252    q31,
    270253} FPRegisterID;
    271254
     
    278261public:
    279262    typedef ARM64Registers::RegisterID RegisterID;
     263    typedef ARM64Registers::SPRegisterID SPRegisterID;
    280264    typedef ARM64Registers::FPRegisterID FPRegisterID;
    281265   
    282266    static constexpr RegisterID firstRegister() { return ARM64Registers::x0; }
    283267    static constexpr RegisterID lastRegister() { return ARM64Registers::sp; }
    284    
     268    static constexpr unsigned numberOfRegisters() { return lastRegister() - firstRegister() + 1; }
     269
     270    static constexpr SPRegisterID firstSPRegister() { return ARM64Registers::pc; }
     271    static constexpr SPRegisterID lastSPRegister() { return ARM64Registers::fpsr; }
     272    static constexpr unsigned numberOfSPRegisters() { return lastSPRegister() - firstSPRegister() + 1; }
     273
    285274    static constexpr FPRegisterID firstFPRegister() { return ARM64Registers::q0; }
    286275    static constexpr FPRegisterID lastFPRegister() { return ARM64Registers::q31; }
     276    static constexpr unsigned numberOfFPRegisters() { return lastFPRegister() - firstFPRegister() + 1; }
     277
     278    static const char* gprName(RegisterID id)
     279    {
     280        ASSERT(id >= firstRegister() && id <= lastRegister());
     281        static const char* const nameForRegister[numberOfRegisters()] = {
     282            "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
     283            "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
     284            "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
     285            "r24", "r25", "r26", "r27", "r28", "fp", "lr", "sp"
     286        };
     287        return nameForRegister[id];
     288    }
     289
     290    static const char* sprName(SPRegisterID id)
     291    {
     292        ASSERT(id >= firstSPRegister() && id <= lastSPRegister());
     293        static const char* const nameForRegister[numberOfSPRegisters()] = {
     294            "pc", "nzcv", "fpsr"
     295        };
     296        return nameForRegister[id];
     297    }
     298
     299    static const char* fprName(FPRegisterID id)
     300    {
     301        ASSERT(id >= firstFPRegister() && id <= lastFPRegister());
     302        static const char* const nameForRegister[numberOfFPRegisters()] = {
     303            "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
     304            "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
     305            "q16", "q17", "q18", "q19", "q20", "q21", "q22", "q23",
     306            "q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31"
     307        };
     308        return nameForRegister[id];
     309    }
    287310
    288311private:
Note: See TracChangeset for help on using the changeset viewer.