diff options
author | dim <dim@FreeBSD.org> | 2014-03-26 07:31:57 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-26 07:31:57 +0000 |
commit | fb422e6d310915f9e2641190198698d922f7ef58 (patch) | |
tree | 8126abc77e6620e23932d186c7b2b75457af47a5 /contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td | |
parent | 5a582ae617991f602ee6f8a954a36fd749aa466c (diff) | |
download | FreeBSD-src-fb422e6d310915f9e2641190198698d922f7ef58.zip FreeBSD-src-fb422e6d310915f9e2641190198698d922f7ef58.tar.gz |
MFC r262613:
Merge the projects/clang-sparc64 branch back to head. This brings in
several updates from the llvm and clang trunks to make the sparc64
backend fully functional.
Apart from one patch to sys/sparc64/include/pcpu.h which is still under
discussion, this makes it possible to let clang fully build world and
kernel for sparc64.
Any assistance with testing this on actual sparc64 hardware is greatly
appreciated, as there will unavoidably be bugs left.
Many thanks go to Roman Divacky for his upstream work on getting the
sparc64 backend into shape.
MFC r262985:
Repair a few minor mismerges from r262261 in the clang-sparc64 project
branch. This is also to minimize differences with upstream.
Diffstat (limited to 'contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td')
-rw-r--r-- | contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td | 277 |
1 files changed, 186 insertions, 91 deletions
diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td b/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td index 8656de5..a5b48f9 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td +++ b/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td @@ -141,41 +141,43 @@ def : Pat<(i64 imm:$val), let Predicates = [Is64Bit] in { // Register-register instructions. - -def : Pat<(and i64:$a, i64:$b), (ANDrr $a, $b)>; -def : Pat<(or i64:$a, i64:$b), (ORrr $a, $b)>; -def : Pat<(xor i64:$a, i64:$b), (XORrr $a, $b)>; - -def : Pat<(and i64:$a, (not i64:$b)), (ANDNrr $a, $b)>; -def : Pat<(or i64:$a, (not i64:$b)), (ORNrr $a, $b)>; -def : Pat<(xor i64:$a, (not i64:$b)), (XNORrr $a, $b)>; - -def : Pat<(add i64:$a, i64:$b), (ADDrr $a, $b)>; -def : Pat<(sub i64:$a, i64:$b), (SUBrr $a, $b)>; - -def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>; - -def : Pat<(tlsadd i64:$a, i64:$b, tglobaltlsaddr:$sym), - (TLS_ADDrr $a, $b, $sym)>; - -// Register-immediate instructions. - -def : Pat<(and i64:$a, (i64 simm13:$b)), (ANDri $a, (as_i32imm $b))>; -def : Pat<(or i64:$a, (i64 simm13:$b)), (ORri $a, (as_i32imm $b))>; -def : Pat<(xor i64:$a, (i64 simm13:$b)), (XORri $a, (as_i32imm $b))>; - -def : Pat<(add i64:$a, (i64 simm13:$b)), (ADDri $a, (as_i32imm $b))>; -def : Pat<(sub i64:$a, (i64 simm13:$b)), (SUBri $a, (as_i32imm $b))>; - -def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>; - -def : Pat<(ctpop i64:$src), (POPCrr $src)>; +let isCodeGenOnly = 1 in { +defm ANDX : F3_12<"and", 0b000001, and, I64Regs, i64, i64imm>; +defm ORX : F3_12<"or", 0b000010, or, I64Regs, i64, i64imm>; +defm XORX : F3_12<"xor", 0b000011, xor, I64Regs, i64, i64imm>; + +def ANDXNrr : F3_1<2, 0b000101, + (outs I64Regs:$dst), (ins I64Regs:$b, I64Regs:$c), + "andn $b, $c, $dst", + [(set i64:$dst, (and i64:$b, (not i64:$c)))]>; +def ORXNrr : F3_1<2, 0b000110, + (outs I64Regs:$dst), (ins I64Regs:$b, I64Regs:$c), + "orn $b, $c, $dst", + [(set i64:$dst, (or i64:$b, (not i64:$c)))]>; +def XNORXrr : F3_1<2, 0b000111, + (outs I64Regs:$dst), (ins I64Regs:$b, I64Regs:$c), + "xnor $b, $c, $dst", + [(set i64:$dst, (not (xor i64:$b, i64:$c)))]>; + +defm ADDX : F3_12<"add", 0b000000, add, I64Regs, i64, i64imm>; +defm SUBX : F3_12<"sub", 0b000100, sub, I64Regs, i64, i64imm>; + +def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$rd), + (ins I64Regs:$rs1, I64Regs:$rs2, TLSSym:$sym), + "add $rs1, $rs2, $rd, $sym", + [(set i64:$rd, + (tlsadd i64:$rs1, i64:$rs2, tglobaltlsaddr:$sym))]>; // "LEA" form of add def LEAX_ADDri : F3_2<2, 0b000000, (outs I64Regs:$dst), (ins MEMri:$addr), "add ${addr:arith}, $dst", [(set iPTR:$dst, ADDRri:$addr)]>; +} + +def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>; +def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>; +def : Pat<(ctpop i64:$src), (POPCrr $src)>; } // Predicates = [Is64Bit] @@ -191,9 +193,9 @@ def MULXrr : F3_1<2, 0b001001, "mulx $rs1, $rs2, $rd", [(set i64:$rd, (mul i64:$rs1, i64:$rs2))]>; def MULXri : F3_2<2, 0b001001, - (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$i), - "mulx $rs1, $i, $rd", - [(set i64:$rd, (mul i64:$rs1, (i64 simm13:$i)))]>; + (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$simm13), + "mulx $rs1, $simm13, $rd", + [(set i64:$rd, (mul i64:$rs1, (i64 simm13:$simm13)))]>; // Division can trap. let hasSideEffects = 1 in { @@ -202,18 +204,18 @@ def SDIVXrr : F3_1<2, 0b101101, "sdivx $rs1, $rs2, $rd", [(set i64:$rd, (sdiv i64:$rs1, i64:$rs2))]>; def SDIVXri : F3_2<2, 0b101101, - (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$i), - "sdivx $rs1, $i, $rd", - [(set i64:$rd, (sdiv i64:$rs1, (i64 simm13:$i)))]>; + (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$simm13), + "sdivx $rs1, $simm13, $rd", + [(set i64:$rd, (sdiv i64:$rs1, (i64 simm13:$simm13)))]>; def UDIVXrr : F3_1<2, 0b001101, (outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2), "udivx $rs1, $rs2, $rd", [(set i64:$rd, (udiv i64:$rs1, i64:$rs2))]>; def UDIVXri : F3_2<2, 0b001101, - (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$i), - "udivx $rs1, $i, $rd", - [(set i64:$rd, (udiv i64:$rs1, (i64 simm13:$i)))]>; + (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$simm13), + "udivx $rs1, $simm13, $rd", + [(set i64:$rd, (udiv i64:$rs1, (i64 simm13:$simm13)))]>; } // hasSideEffects = 1 } // Predicates = [Is64Bit] @@ -233,15 +235,9 @@ def UDIVXri : F3_2<2, 0b001101, let Predicates = [Is64Bit] in { // 64-bit loads. -def LDXrr : F3_1<3, 0b001011, - (outs I64Regs:$dst), (ins MEMrr:$addr), - "ldx [$addr], $dst", - [(set i64:$dst, (load ADDRrr:$addr))]>; -def LDXri : F3_2<3, 0b001011, - (outs I64Regs:$dst), (ins MEMri:$addr), - "ldx [$addr], $dst", - [(set i64:$dst, (load ADDRri:$addr))]>; -let mayLoad = 1 in +defm LDX : Load<"ldx", 0b001011, load, I64Regs, i64>; + +let mayLoad = 1, isCodeGenOnly = 1, isAsmParserOnly = 1 in def TLS_LDXrr : F3_1<3, 0b001011, (outs IntRegs:$dst), (ins MEMrr:$addr, TLSSym:$sym), "ldx [$addr], $dst, $sym", @@ -274,24 +270,10 @@ def : Pat<(i64 (extloadi32 ADDRrr:$addr)), (LDrr ADDRrr:$addr)>; def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>; // Sign-extending load of i32 into i64 is a new SPARC v9 instruction. -def LDSWrr : F3_1<3, 0b001011, - (outs I64Regs:$dst), (ins MEMrr:$addr), - "ldsw [$addr], $dst", - [(set i64:$dst, (sextloadi32 ADDRrr:$addr))]>; -def LDSWri : F3_2<3, 0b001011, - (outs I64Regs:$dst), (ins MEMri:$addr), - "ldsw [$addr], $dst", - [(set i64:$dst, (sextloadi32 ADDRri:$addr))]>; +defm LDSW : Load<"ldsw", 0b001000, sextloadi32, I64Regs, i64>; // 64-bit stores. -def STXrr : F3_1<3, 0b001110, - (outs), (ins MEMrr:$addr, I64Regs:$src), - "stx $src, [$addr]", - [(store i64:$src, ADDRrr:$addr)]>; -def STXri : F3_2<3, 0b001110, - (outs), (ins MEMri:$addr, I64Regs:$src), - "stx $src, [$addr]", - [(store i64:$src, ADDRri:$addr)]>; +defm STX : Store<"stx", 0b001110, store, I64Regs, i64>; // Truncating stores from i64 are identical to the i32 stores. def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>; @@ -311,6 +293,15 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADDRri:$dst, (i64 G0))>; //===----------------------------------------------------------------------===// // 64-bit Conditionals. //===----------------------------------------------------------------------===// + +// Conditional branch class on %xcc: +class XBranchSP<dag ins, string asmstr, list<dag> pattern> + : F2_3<0b001, 0b10, (outs), ins, asmstr, pattern> { + let isBranch = 1; + let isTerminator = 1; + let hasDelaySlot = 1; +} + // // Flag-setting instructions like subcc and addcc set both icc and xcc flags. // The icc flags correspond to the 32-bit result, and the xcc are for the @@ -322,32 +313,42 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADDRri:$dst, (i64 G0))>; let Predicates = [Is64Bit] in { let Uses = [ICC] in -def BPXCC : BranchSP<(ins brtarget:$imm22, CCOp:$cond), - "b$cond %xcc, $imm22", - [(SPbrxcc bb:$imm22, imm:$cond)]>; +def BPXCC : XBranchSP<(ins brtarget:$imm19, CCOp:$cond), + "b$cond %xcc, $imm19", + [(SPbrxcc bb:$imm19, imm:$cond)]>; // Conditional moves on %xcc. let Uses = [ICC], Constraints = "$f = $rd" in { -def MOVXCCrr : Pseudo<(outs IntRegs:$rd), +let cc = 0b110 in { +def MOVXCCrr : F4_1<0b101100, (outs IntRegs:$rd), (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond), "mov$cond %xcc, $rs2, $rd", [(set i32:$rd, (SPselectxcc i32:$rs2, i32:$f, imm:$cond))]>; -def MOVXCCri : Pseudo<(outs IntRegs:$rd), - (ins i32imm:$i, IntRegs:$f, CCOp:$cond), - "mov$cond %xcc, $i, $rd", +def MOVXCCri : F4_2<0b101100, (outs IntRegs:$rd), + (ins i32imm:$simm11, IntRegs:$f, CCOp:$cond), + "mov$cond %xcc, $simm11, $rd", [(set i32:$rd, - (SPselectxcc simm11:$i, i32:$f, imm:$cond))]>; -def FMOVS_XCC : Pseudo<(outs FPRegs:$rd), + (SPselectxcc simm11:$simm11, i32:$f, imm:$cond))]>; +} // cc + +let opf_cc = 0b110 in { +def FMOVS_XCC : F4_3<0b110101, 0b000001, (outs FPRegs:$rd), (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond), "fmovs$cond %xcc, $rs2, $rd", [(set f32:$rd, (SPselectxcc f32:$rs2, f32:$f, imm:$cond))]>; -def FMOVD_XCC : Pseudo<(outs DFPRegs:$rd), +def FMOVD_XCC : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), "fmovd$cond %xcc, $rs2, $rd", [(set f64:$rd, (SPselectxcc f64:$rs2, f64:$f, imm:$cond))]>; +def FMOVQ_XCC : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), + (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), + "fmovq$cond %xcc, $rs2, $rd", + [(set f128:$rd, + (SPselectxcc f128:$rs2, f128:$f, imm:$cond))]>; +} // opf_cc } // Uses, Constraints //===----------------------------------------------------------------------===// @@ -357,31 +358,31 @@ def FMOVD_XCC : Pseudo<(outs DFPRegs:$rd), let Predicates = [Is64Bit] in { def FXTOS : F3_3u<2, 0b110100, 0b010000100, - (outs FPRegs:$dst), (ins DFPRegs:$src), - "fxtos $src, $dst", - [(set FPRegs:$dst, (SPxtof DFPRegs:$src))]>; + (outs FPRegs:$rd), (ins DFPRegs:$rs2), + "fxtos $rs2, $rd", + [(set FPRegs:$rd, (SPxtof DFPRegs:$rs2))]>; def FXTOD : F3_3u<2, 0b110100, 0b010001000, - (outs DFPRegs:$dst), (ins DFPRegs:$src), - "fxtod $src, $dst", - [(set DFPRegs:$dst, (SPxtof DFPRegs:$src))]>; + (outs DFPRegs:$rd), (ins DFPRegs:$rs2), + "fxtod $rs2, $rd", + [(set DFPRegs:$rd, (SPxtof DFPRegs:$rs2))]>; def FXTOQ : F3_3u<2, 0b110100, 0b010001100, - (outs QFPRegs:$dst), (ins DFPRegs:$src), - "fxtoq $src, $dst", - [(set QFPRegs:$dst, (SPxtof DFPRegs:$src))]>, + (outs QFPRegs:$rd), (ins DFPRegs:$rs2), + "fxtoq $rs2, $rd", + [(set QFPRegs:$rd, (SPxtof DFPRegs:$rs2))]>, Requires<[HasHardQuad]>; def FSTOX : F3_3u<2, 0b110100, 0b010000001, - (outs DFPRegs:$dst), (ins FPRegs:$src), - "fstox $src, $dst", - [(set DFPRegs:$dst, (SPftox FPRegs:$src))]>; + (outs DFPRegs:$rd), (ins FPRegs:$rs2), + "fstox $rs2, $rd", + [(set DFPRegs:$rd, (SPftox FPRegs:$rs2))]>; def FDTOX : F3_3u<2, 0b110100, 0b010000010, - (outs DFPRegs:$dst), (ins DFPRegs:$src), - "fdtox $src, $dst", - [(set DFPRegs:$dst, (SPftox DFPRegs:$src))]>; + (outs DFPRegs:$rd), (ins DFPRegs:$rs2), + "fdtox $rs2, $rd", + [(set DFPRegs:$rd, (SPftox DFPRegs:$rs2))]>; def FQTOX : F3_3u<2, 0b110100, 0b010000011, - (outs DFPRegs:$dst), (ins QFPRegs:$src), - "fqtox $src, $dst", - [(set DFPRegs:$dst, (SPftox QFPRegs:$src))]>, + (outs DFPRegs:$rd), (ins QFPRegs:$rs2), + "fqtox $rs2, $rd", + [(set DFPRegs:$rd, (SPftox QFPRegs:$rs2))]>, Requires<[HasHardQuad]>; } // Predicates = [Is64Bit] @@ -402,3 +403,97 @@ def : Pat<(SPselectfcc (i64 simm11:$t), i64:$f, imm:$cond), (MOVFCCri (as_i32imm $t), $f, imm:$cond)>; } // Predicates = [Is64Bit] + + +// 64 bit SETHI +let Predicates = [Is64Bit], isCodeGenOnly = 1 in { +def SETHIXi : F2_1<0b100, + (outs IntRegs:$rd), (ins i64imm:$imm22), + "sethi $imm22, $rd", + [(set i64:$rd, SETHIimm:$imm22)]>; +} + +// ATOMICS. +let Predicates = [Is64Bit], Constraints = "$swap = $rd" in { + def CASXrr: F3_1_asi<3, 0b111110, 0b10000000, + (outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2, + I64Regs:$swap), + "casx [$rs1], $rs2, $rd", + [(set i64:$rd, + (atomic_cmp_swap i64:$rs1, i64:$rs2, i64:$swap))]>; + +} // Predicates = [Is64Bit], Constraints = ... + +let Predicates = [Is64Bit] in { + +def : Pat<(atomic_fence imm, imm), (MEMBARi 0xf)>; + +// atomic_load_64 addr -> load addr +def : Pat<(i64 (atomic_load ADDRrr:$src)), (LDXrr ADDRrr:$src)>; +def : Pat<(i64 (atomic_load ADDRri:$src)), (LDXri ADDRri:$src)>; + +// atomic_store_64 val, addr -> store val, addr +def : Pat<(atomic_store ADDRrr:$dst, i64:$val), (STXrr ADDRrr:$dst, $val)>; +def : Pat<(atomic_store ADDRri:$dst, i64:$val), (STXri ADDRri:$dst, $val)>; + +} // Predicates = [Is64Bit] + +let usesCustomInserter = 1, hasCtrlDep = 1, mayLoad = 1, mayStore = 1, + Defs = [ICC] in +multiclass AtomicRMW<SDPatternOperator op32, SDPatternOperator op64> { + + def _32 : Pseudo<(outs IntRegs:$rd), + (ins ptr_rc:$addr, IntRegs:$rs2), "", + [(set i32:$rd, (op32 iPTR:$addr, i32:$rs2))]>; + + let Predicates = [Is64Bit] in + def _64 : Pseudo<(outs I64Regs:$rd), + (ins ptr_rc:$addr, I64Regs:$rs2), "", + [(set i64:$rd, (op64 iPTR:$addr, i64:$rs2))]>; +} + +defm ATOMIC_LOAD_ADD : AtomicRMW<atomic_load_add_32, atomic_load_add_64>; +defm ATOMIC_LOAD_SUB : AtomicRMW<atomic_load_sub_32, atomic_load_sub_64>; +defm ATOMIC_LOAD_AND : AtomicRMW<atomic_load_and_32, atomic_load_and_64>; +defm ATOMIC_LOAD_OR : AtomicRMW<atomic_load_or_32, atomic_load_or_64>; +defm ATOMIC_LOAD_XOR : AtomicRMW<atomic_load_xor_32, atomic_load_xor_64>; +defm ATOMIC_LOAD_NAND : AtomicRMW<atomic_load_nand_32, atomic_load_nand_64>; +defm ATOMIC_LOAD_MIN : AtomicRMW<atomic_load_min_32, atomic_load_min_64>; +defm ATOMIC_LOAD_MAX : AtomicRMW<atomic_load_max_32, atomic_load_max_64>; +defm ATOMIC_LOAD_UMIN : AtomicRMW<atomic_load_umin_32, atomic_load_umin_64>; +defm ATOMIC_LOAD_UMAX : AtomicRMW<atomic_load_umax_32, atomic_load_umax_64>; + +// There is no 64-bit variant of SWAP, so use a pseudo. +let usesCustomInserter = 1, hasCtrlDep = 1, mayLoad = 1, mayStore = 1, + Defs = [ICC], Predicates = [Is64Bit] in +def ATOMIC_SWAP_64 : Pseudo<(outs I64Regs:$rd), + (ins ptr_rc:$addr, I64Regs:$rs2), "", + [(set i64:$rd, + (atomic_swap_64 iPTR:$addr, i64:$rs2))]>; + +// Global addresses, constant pool entries +let Predicates = [Is64Bit] in { + +def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>; +def : Pat<(SPlo tglobaladdr:$in), (ORXri (i64 G0), tglobaladdr:$in)>; +def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>; +def : Pat<(SPlo tconstpool:$in), (ORXri (i64 G0), tconstpool:$in)>; + +// GlobalTLS addresses +def : Pat<(SPhi tglobaltlsaddr:$in), (SETHIi tglobaltlsaddr:$in)>; +def : Pat<(SPlo tglobaltlsaddr:$in), (ORXri (i64 G0), tglobaltlsaddr:$in)>; +def : Pat<(add (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)), + (ADDXri (SETHIXi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>; +def : Pat<(xor (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)), + (XORXri (SETHIXi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>; + +// Blockaddress +def : Pat<(SPhi tblockaddress:$in), (SETHIi tblockaddress:$in)>; +def : Pat<(SPlo tblockaddress:$in), (ORXri (i64 G0), tblockaddress:$in)>; + +// Add reg, lo. This is used when taking the addr of a global/constpool entry. +def : Pat<(add iPTR:$r, (SPlo tglobaladdr:$in)), (ADDXri $r, tglobaladdr:$in)>; +def : Pat<(add iPTR:$r, (SPlo tconstpool:$in)), (ADDXri $r, tconstpool:$in)>; +def : Pat<(add iPTR:$r, (SPlo tblockaddress:$in)), + (ADDXri $r, tblockaddress:$in)>; +} |