diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 72528c73b19..1432d1306db 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -657,15 +657,55 @@ X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm, // getDwarfRegNum - This function maps LLVM register identifiers to the // Dwarf specific numbering, used in debug info and exception tables. // The registers are given "basic" dwarf numbers in the .td files, -// which are collected by TableGen into X86GenRegisterInfo::getDwarfRegNum. -// This wrapper allows for target-specific overrides. +// which are for the 64-bit target. These are collected by TableGen +// into X86GenRegisterInfo::getDwarfRegNum and overridden here for +// other targets. +// FIXME: Comments in gcc indicate that Darwin uses different numbering +// for debug info and exception handling info:( The numbering here is +// for exception handling. + int X86RegisterInfo::getDwarfRegNum(unsigned RegNo) const { int n = X86GenRegisterInfo::getDwarfRegNum(RegNo); const X86Subtarget *Subtarget = &TM.getSubtarget(); - if (Subtarget->isDarwin) { - // ESP and EBP are switched. - if (n==4) return 5; - if (n==5) return 4; + if (!Subtarget->is64Bit()) { + // Numbers are all different for 32-bit. Further, some of them + // differ between Darwin and other targets. + switch (n) { + default: assert(0 && "Invalid argument to getDwarfRegNum"); + return n; + case 0: return 0; // ax + case 1: return 2; // dx + case 2: return 1; // cx + case 3: return 3; // bx + case 4: return 6; // si + case 5: return 7; // di + case 6: return (Subtarget->isDarwin) ? 4 : 5; // bp + case 7: return (Subtarget->isDarwin) ? 5 : 4; // sp + + case 8: case 9: case 10: case 11: // r8..r15 + case 12: case 13: case 14: case 15: + assert(0 && "Invalid register in 32-bit mode"); + return n; + + case 16: return 8; // ip + + case 17: case 18: case 19: case 20: // xmm0..xmm7 + case 21: case 22: case 23: case 24: + return n+4; + + case 25: case 26: case 27: case 28: // xmm8..xmm15 + case 29: case 30: case 31: case 32: + assert(0 && "Invalid register in 32-bit mode"); + return n; + + case 33: case 34: case 35: case 36: // st0..st7 + case 37: case 38: case 39: case 40: + return (Subtarget->isDarwin) ? n-21 : n-22; + + case 41: case 42: case 43: case 44: // mm0..mm7 + case 45: case 46: case 47: case 48: + return n-12; + } } return n; } diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index 2ebc8ab127b..4fc23a223fb 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -23,12 +23,17 @@ let Namespace = "X86" in { // because the register file generator is smart enough to figure out that // AL aliases AX if we tell it that AX aliased AL (for example). - // FIXME: X86-64 have different Dwarf numbers. + // Dwarf numbering is different for 32-bit and 64-bit, and there are + // variations by target as well. The numbers here are for 64-bit. + // They are altered by X86RegisterInfo::getDwarfRegNum at runtime. Note + // that we can't assign the same number here to different registers, as + // getDwarfRegNum has only the number here to work with. + // 8-bit registers // Low registers def AL : Register<"AL">, DwarfRegNum<0>; - def CL : Register<"CL">, DwarfRegNum<1>; - def DL : Register<"DL">, DwarfRegNum<2>; + def DL : Register<"DL">, DwarfRegNum<1>; + def CL : Register<"CL">, DwarfRegNum<2>; def BL : Register<"BL">, DwarfRegNum<3>; // X86-64 only @@ -47,20 +52,20 @@ let Namespace = "X86" in { // High registers X86-32 only def AH : Register<"AH">, DwarfRegNum<0>; - def CH : Register<"CH">, DwarfRegNum<1>; - def DH : Register<"DH">, DwarfRegNum<2>; + def DH : Register<"DH">, DwarfRegNum<1>; + def CH : Register<"CH">, DwarfRegNum<2>; def BH : Register<"BH">, DwarfRegNum<3>; // 16-bit registers def AX : RegisterWithSubRegs<"AX", [AH,AL]>, DwarfRegNum<0>; - def CX : RegisterWithSubRegs<"CX", [CH,CL]>, DwarfRegNum<1>; - def DX : RegisterWithSubRegs<"DX", [DH,DL]>, DwarfRegNum<2>; + def DX : RegisterWithSubRegs<"DX", [DH,DL]>, DwarfRegNum<1>; + def CX : RegisterWithSubRegs<"CX", [CH,CL]>, DwarfRegNum<2>; def BX : RegisterWithSubRegs<"BX", [BH,BL]>, DwarfRegNum<3>; - def SP : RegisterWithSubRegs<"SP", [SPL]>, DwarfRegNum<4>; - def BP : RegisterWithSubRegs<"BP", [BPL]>, DwarfRegNum<5>; - def SI : RegisterWithSubRegs<"SI", [SIL]>, DwarfRegNum<6>; - def DI : RegisterWithSubRegs<"DI", [DIL]>, DwarfRegNum<7>; - def IP : Register<"IP">, DwarfRegNum<8>; + def SI : RegisterWithSubRegs<"SI", [SIL]>, DwarfRegNum<4>; + def DI : RegisterWithSubRegs<"DI", [DIL]>, DwarfRegNum<5>; + def BP : RegisterWithSubRegs<"BP", [BPL]>, DwarfRegNum<6>; + def SP : RegisterWithSubRegs<"SP", [SPL]>, DwarfRegNum<7>; + def IP : Register<"IP">, DwarfRegNum<16>; // X86-64 only def R8W : RegisterWithSubRegs<"R8W", [R8B]>, DwarfRegNum<8>; @@ -74,14 +79,14 @@ let Namespace = "X86" in { // 32-bit registers def EAX : RegisterWithSubRegs<"EAX", [AX]>, DwarfRegNum<0>; - def ECX : RegisterWithSubRegs<"ECX", [CX]>, DwarfRegNum<1>; - def EDX : RegisterWithSubRegs<"EDX", [DX]>, DwarfRegNum<2>; + def EDX : RegisterWithSubRegs<"EDX", [DX]>, DwarfRegNum<1>; + def ECX : RegisterWithSubRegs<"ECX", [CX]>, DwarfRegNum<2>; def EBX : RegisterWithSubRegs<"EBX", [BX]>, DwarfRegNum<3>; - def ESP : RegisterWithSubRegs<"ESP", [SP]>, DwarfRegNum<4>; - def EBP : RegisterWithSubRegs<"EBP", [BP]>, DwarfRegNum<5>; - def ESI : RegisterWithSubRegs<"ESI", [SI]>, DwarfRegNum<6>; - def EDI : RegisterWithSubRegs<"EDI", [DI]>, DwarfRegNum<7>; - def EIP : RegisterWithSubRegs<"EIP", [IP]>, DwarfRegNum<8>; + def ESI : RegisterWithSubRegs<"ESI", [SI]>, DwarfRegNum<4>; + def EDI : RegisterWithSubRegs<"EDI", [DI]>, DwarfRegNum<5>; + def EBP : RegisterWithSubRegs<"EBP", [BP]>, DwarfRegNum<6>; + def ESP : RegisterWithSubRegs<"ESP", [SP]>, DwarfRegNum<7>; + def EIP : RegisterWithSubRegs<"EIP", [IP]>, DwarfRegNum<16>; // X86-64 only def R8D : RegisterWithSubRegs<"R8D", [R8W]>, DwarfRegNum<8>; @@ -114,14 +119,14 @@ let Namespace = "X86" in { def RIP : RegisterWithSubRegs<"RIP", [EIP]>, DwarfRegNum<16>; // MMX Registers. These are actually aliased to ST0 .. ST7 - def MM0 : Register<"MM0">, DwarfRegNum<29>; - def MM1 : Register<"MM1">, DwarfRegNum<30>; - def MM2 : Register<"MM2">, DwarfRegNum<31>; - def MM3 : Register<"MM3">, DwarfRegNum<32>; - def MM4 : Register<"MM4">, DwarfRegNum<33>; - def MM5 : Register<"MM5">, DwarfRegNum<34>; - def MM6 : Register<"MM6">, DwarfRegNum<35>; - def MM7 : Register<"MM7">, DwarfRegNum<36>; + def MM0 : Register<"MM0">, DwarfRegNum<41>; + def MM1 : Register<"MM1">, DwarfRegNum<42>; + def MM2 : Register<"MM2">, DwarfRegNum<43>; + def MM3 : Register<"MM3">, DwarfRegNum<44>; + def MM4 : Register<"MM4">, DwarfRegNum<45>; + def MM5 : Register<"MM5">, DwarfRegNum<46>; + def MM6 : Register<"MM6">, DwarfRegNum<47>; + def MM7 : Register<"MM7">, DwarfRegNum<48>; // Pseudo Floating Point registers def FP0 : Register<"FP0">, DwarfRegNum<-1>; @@ -153,14 +158,14 @@ let Namespace = "X86" in { def XMM15: Register<"XMM15">, DwarfRegNum<32>; // Floating point stack registers - def ST0 : Register<"ST(0)">, DwarfRegNum<11>; - def ST1 : Register<"ST(1)">, DwarfRegNum<12>; - def ST2 : Register<"ST(2)">, DwarfRegNum<13>; - def ST3 : Register<"ST(3)">, DwarfRegNum<14>; - def ST4 : Register<"ST(4)">, DwarfRegNum<15>; - def ST5 : Register<"ST(5)">, DwarfRegNum<16>; - def ST6 : Register<"ST(6)">, DwarfRegNum<17>; - def ST7 : Register<"ST(7)">, DwarfRegNum<18>; + def ST0 : Register<"ST(0)">, DwarfRegNum<33>; + def ST1 : Register<"ST(1)">, DwarfRegNum<34>; + def ST2 : Register<"ST(2)">, DwarfRegNum<35>; + def ST3 : Register<"ST(3)">, DwarfRegNum<36>; + def ST4 : Register<"ST(4)">, DwarfRegNum<37>; + def ST5 : Register<"ST(5)">, DwarfRegNum<38>; + def ST6 : Register<"ST(6)">, DwarfRegNum<39>; + def ST7 : Register<"ST(7)">, DwarfRegNum<40>; // Status flags register def EFLAGS : Register<"EFLAGS">;