diff options
author | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2014-03-02 09:46:56 +0000 |
---|---|---|
committer | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2014-03-02 09:46:56 +0000 |
commit | 28713758826720b99be7823f3ba2bb2f50b2e6d0 (patch) | |
tree | c4ebb1fc29ab27be4953bd1356d4b569b9b5fdda /lib/Target/Sparc | |
parent | a9fe27ffb3aeaea3c774d16ea938b10149f348a8 (diff) | |
download | llvm-28713758826720b99be7823f3ba2bb2f50b2e6d0.tar.gz llvm-28713758826720b99be7823f3ba2bb2f50b2e6d0.tar.bz2 llvm-28713758826720b99be7823f3ba2bb2f50b2e6d0.tar.xz |
[SparcV9] Adds support for branch on integer register instructions (BPr) and conditional moves on integer register (MOVr/FMOVr).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202628 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r-- | lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp | 8 | ||||
-rw-r--r-- | lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h | 4 | ||||
-rw-r--r-- | lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp | 20 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcCodeEmitter.cpp | 8 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstr64Bit.td | 78 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrAliases.td | 1 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrFormats.td | 43 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrInfo.td | 4 |
8 files changed, 165 insertions, 1 deletions
diff --git a/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp index f6c5816549..d0621c1c79 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -39,6 +39,12 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { case Sparc::fixup_sparc_br19: return (Value >> 2) & 0x7ffff; + case Sparc::fixup_sparc_br16_2: + return (Value >> 2) & 0xc000; + + case Sparc::fixup_sparc_br16_14: + return (Value >> 2) & 0x3fff; + case Sparc::fixup_sparc_pc22: case Sparc::fixup_sparc_got22: case Sparc::fixup_sparc_tls_gd_hi22: @@ -106,6 +112,8 @@ namespace { { "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_sparc_br16_2", 10, 2, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_sparc_br16_14", 18, 14, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_sparc_hi22", 10, 22, 0 }, { "fixup_sparc_lo10", 22, 10, 0 }, { "fixup_sparc_h44", 10, 22, 0 }, diff --git a/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h b/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h index 005a0242dc..d42bcee6b3 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h +++ b/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h @@ -26,6 +26,10 @@ namespace llvm { /// branches on icc/xcc fixup_sparc_br19, + /// fixup_sparc_bpr - 16-bit fixup for bpr + fixup_sparc_br16_2, + fixup_sparc_br16_14, + /// fixup_sparc_hi22 - 22-bit fixup corresponding to %hi(foo) /// for sethi fixup_sparc_hi22, diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp index 96665ef245..310fbd913c 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp @@ -64,6 +64,10 @@ public: unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; + unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + }; } // end anonymous namespace @@ -192,6 +196,22 @@ getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo, (MCFixupKind)Sparc::fixup_sparc_br19)); return 0; } +unsigned SparcMCCodeEmitter:: +getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isReg() || MO.isImm()) + return getMachineOpValue(MI, MO, Fixups, STI); + + Fixups.push_back(MCFixup::Create(0, MO.getExpr(), + (MCFixupKind)Sparc::fixup_sparc_br16_2)); + Fixups.push_back(MCFixup::Create(0, MO.getExpr(), + (MCFixupKind)Sparc::fixup_sparc_br16_14)); + + return 0; +} + #include "SparcGenMCCodeEmitter.inc" diff --git a/lib/Target/Sparc/SparcCodeEmitter.cpp b/lib/Target/Sparc/SparcCodeEmitter.cpp index 6b5e4bf0f5..97bacf2d31 100644 --- a/lib/Target/Sparc/SparcCodeEmitter.cpp +++ b/lib/Target/Sparc/SparcCodeEmitter.cpp @@ -78,6 +78,8 @@ private: unsigned) const; unsigned getBranchPredTargetOpValue(const MachineInstr &MI, unsigned) const; + unsigned getBranchOnRegTargetOpValue(const MachineInstr &MI, + unsigned) const; void emitWord(unsigned Word); @@ -206,6 +208,12 @@ unsigned SparcCodeEmitter::getBranchPredTargetOpValue(const MachineInstr &MI, return getMachineOpValue(MI, MO); } +unsigned SparcCodeEmitter::getBranchOnRegTargetOpValue(const MachineInstr &MI, + unsigned opIdx) const { + const MachineOperand MO = MI.getOperand(opIdx); + return getMachineOpValue(MI, MO); +} + unsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI, const MachineOperand &MO) const { diff --git a/lib/Target/Sparc/SparcInstr64Bit.td b/lib/Target/Sparc/SparcInstr64Bit.td index 9232860ba6..9ac0e80617 100644 --- a/lib/Target/Sparc/SparcInstr64Bit.td +++ b/lib/Target/Sparc/SparcInstr64Bit.td @@ -344,6 +344,84 @@ def FMOVQ_XCC : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), } // opf_cc } // Uses, Constraints +// Branch On integer register with Prediction (BPr). +let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in +multiclass BranchOnReg<bits<3> cond, string OpcStr> { + def napt : F2_4<cond, 0, 1, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16), + !strconcat(OpcStr, " $rs1, $imm16"), []>; + def apt : F2_4<cond, 1, 1, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16), + !strconcat(OpcStr, ",a $rs1, $imm16"), []>; + def napn : F2_4<cond, 0, 0, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16), + !strconcat(OpcStr, ",pn $rs1, $imm16"), []>; + def apn : F2_4<cond, 1, 0, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16), + !strconcat(OpcStr, ",a,pn $rs1, $imm16"), []>; +} + +multiclass bpr_alias<string OpcStr, Instruction NAPT, Instruction APT> { + def : InstAlias<!strconcat(OpcStr, ",pt $rs1, $imm16"), + (NAPT I64Regs:$rs1, bprtarget16:$imm16)>; + def : InstAlias<!strconcat(OpcStr, ",a,pt $rs1, $imm16"), + (APT I64Regs:$rs1, bprtarget16:$imm16)>; +} + +defm BPZ : BranchOnReg<0b001, "brz">; +defm BPLEZ : BranchOnReg<0b010, "brlez">; +defm BPLZ : BranchOnReg<0b011, "brlz">; +defm BPNZ : BranchOnReg<0b101, "brnz">; +defm BPGZ : BranchOnReg<0b110, "brgz">; +defm BPGEZ : BranchOnReg<0b111, "brgez">; + +defm : bpr_alias<"brz", BPZnapt, BPZapt >; +defm : bpr_alias<"brlez", BPLEZnapt, BPLEZapt>; +defm : bpr_alias<"brlz", BPLZnapt, BPLZapt >; +defm : bpr_alias<"brnz", BPNZnapt, BPNZapt >; +defm : bpr_alias<"brgz", BPGZnapt, BPGZapt >; +defm : bpr_alias<"brgez", BPGEZnapt, BPGEZapt>; + +// Move integer register on register condition (MOVr). +multiclass MOVR< bits<3> rcond, string OpcStr> { + def rr : F4_4r<0b101111, 0b00000, rcond, (outs I64Regs:$rd), + (ins I64Regs:$rs1, IntRegs:$rs2), + !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>; + + def ri : F4_4i<0b101111, rcond, (outs I64Regs:$rd), + (ins I64Regs:$rs1, i64imm:$simm10), + !strconcat(OpcStr, " $rs1, $simm10, $rd"), []>; +} + +defm MOVRRZ : MOVR<0b001, "movrz">; +defm MOVRLEZ : MOVR<0b010, "movrlez">; +defm MOVRLZ : MOVR<0b011, "movrlz">; +defm MOVRNZ : MOVR<0b101, "movrnz">; +defm MOVRGZ : MOVR<0b110, "movrgz">; +defm MOVRGEZ : MOVR<0b111, "movrgez">; + +// Move FP register on integer register condition (FMOVr). +multiclass FMOVR<bits<3> rcond, string OpcStr> { + + def S : F4_4r<0b110101, 0b00101, rcond, + (outs FPRegs:$rd), (ins I64Regs:$rs1, FPRegs:$rs2), + !strconcat(!strconcat("fmovrs", OpcStr)," $rs1, $rs2, $rd"), + []>; + def D : F4_4r<0b110101, 0b00110, rcond, + (outs FPRegs:$rd), (ins I64Regs:$rs1, FPRegs:$rs2), + !strconcat(!strconcat("fmovrd", OpcStr)," $rs1, $rs2, $rd"), + []>; + def Q : F4_4r<0b110101, 0b00111, rcond, + (outs FPRegs:$rd), (ins I64Regs:$rs1, FPRegs:$rs2), + !strconcat(!strconcat("fmovrq", OpcStr)," $rs1, $rs2, $rd"), + []>, Requires<[HasHardQuad]>; +} + +let Predicates = [HasV9] in { + defm FMOVRZ : FMOVR<0b001, "z">; + defm FMOVRLEZ : FMOVR<0b010, "lez">; + defm FMOVRLZ : FMOVR<0b011, "lz">; + defm FMOVRNZ : FMOVR<0b101, "nz">; + defm FMOVRGZ : FMOVR<0b110, "gz">; + defm FMOVRGEZ : FMOVR<0b111, "gez">; +} + //===----------------------------------------------------------------------===// // 64-bit Floating Point Conversions. //===----------------------------------------------------------------------===// diff --git a/lib/Target/Sparc/SparcInstrAliases.td b/lib/Target/Sparc/SparcInstrAliases.td index dc35544daa..0ab93706df 100644 --- a/lib/Target/Sparc/SparcInstrAliases.td +++ b/lib/Target/Sparc/SparcInstrAliases.td @@ -224,7 +224,6 @@ defm : fp_cond_alias<"le", 0b1101>; defm : fp_cond_alias<"ule", 0b1110>; defm : fp_cond_alias<"o", 0b1111>; - // Instruction aliases for JMPL. // jmp addr -> jmpl addr, %g0 diff --git a/lib/Target/Sparc/SparcInstrFormats.td b/lib/Target/Sparc/SparcInstrFormats.td index 6b0b0ce16a..1ce25904f3 100644 --- a/lib/Target/Sparc/SparcInstrFormats.td +++ b/lib/Target/Sparc/SparcInstrFormats.td @@ -77,6 +77,25 @@ class F2_3<bits<3> op2Val, bit annul, bit pred, let Inst{18-0} = imm19; } +class F2_4<bits<3> cond, bit annul, bit pred, + dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSP<outs, ins, asmstr, pattern> { + bits<16> imm16; + bits<5> rs1; + + let op = 0; // op = 0 + + let Inst{29} = annul; + let Inst{28} = 0; + let Inst{27-25} = cond; + let Inst{24-22} = 0b011; + let Inst{21-20} = imm16{15-14}; + let Inst{19} = pred; + let Inst{18-14} = rs1; + let Inst{13-0} = imm16{13-0}; +} + + //===----------------------------------------------------------------------===// // Format #3 instruction classes in the Sparc //===----------------------------------------------------------------------===// @@ -254,3 +273,27 @@ class F4_3<bits<6> op3, bits<6> opf_low, dag outs, dag ins, let Inst{10-5} = opf_low; let Inst{4-0} = rs2; } + +class F4_4r<bits<6> op3, bits<5> opf_low, bits<3> rcond, dag outs, dag ins, + string asmstr, list<dag> pattern> + : F4<op3, outs, ins, asmstr, pattern> { + bits <5> rs1; + bits <5> rs2; + let Inst{18-14} = rs1; + let Inst{13} = 0; // IsImm + let Inst{12-10} = rcond; + let Inst{9-5} = opf_low; + let Inst{4-0} = rs2; +} + + +class F4_4i<bits<6> op3, bits<3> rcond, dag outs, dag ins, + string asmstr, list<dag> pattern> + : F4<op3, outs, ins, asmstr, pattern> { + bits<5> rs1; + bits<10> simm10; + let Inst{18-14} = rs1; + let Inst{13} = 1; // IsImm + let Inst{12-10} = rcond; + let Inst{9-0} = simm10; +} diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index b4d8ba55fd..c7babc888e 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -109,6 +109,10 @@ def bprtarget : Operand<OtherVT> { let EncoderMethod = "getBranchPredTargetOpValue"; } +def bprtarget16 : Operand<OtherVT> { + let EncoderMethod = "getBranchOnRegTargetOpValue"; +} + def calltarget : Operand<i32> { let EncoderMethod = "getCallTargetOpValue"; let DecoderMethod = "DecodeCall"; |