[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
This commit is contained in:
Venkatraman Govindaraju 2014-03-02 09:46:56 +00:00
parent a9fe27ffb3
commit 2871375882
9 changed files with 243 additions and 1 deletions

View File

@ -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 },

View File

@ -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,

View File

@ -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"

View File

@ -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 {

View File

@ -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.
//===----------------------------------------------------------------------===//

View File

@ -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

View File

@ -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;
}

View File

@ -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";

View File

@ -1136,3 +1136,81 @@
! CHECK: fbne,a,pn %fcc3, .BB0 ! encoding: [0x23,0b01110AAA,A,A]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
fbne,a,pn %fcc3, .BB0
! CHECK: brz %g1, .BB0 ! encoding: [0x02,0b11AA1000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
! CHECK: brlez %g1, .BB0 ! encoding: [0x04,0b11AA1000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
! CHECK: brlz %g1, .BB0 ! encoding: [0x06,0b11AA1000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
! CHECK: brnz %g1, .BB0 ! encoding: [0x0a,0b11AA1000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
! CHECK: brgz %g1, .BB0 ! encoding: [0x0c,0b11AA1000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
! CHECK: brgez %g1, .BB0 ! encoding: [0x0e,0b11AA1000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
brz %g1, .BB0
brlez %g1, .BB0
brlz %g1, .BB0
brnz %g1, .BB0
brgz %g1, .BB0
brgez %g1, .BB0
! CHECK: brz %g1, .BB0 ! encoding: [0x02,0b11AA1000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
brz,pt %g1, .BB0
! CHECK: brz,a %g1, .BB0 ! encoding: [0x22,0b11AA1000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
brz,a %g1, .BB0
! CHECK: brz,a %g1, .BB0 ! encoding: [0x22,0b11AA1000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
brz,a,pt %g1, .BB0
! CHECK: brz,pn %g1, .BB0 ! encoding: [0x02,0b11AA0000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
brz,pn %g1, .BB0
! CHECK: brz,a,pn %g1, .BB0 ! encoding: [0x22,0b11AA0000,0b01BBBBBB,B]
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
brz,a,pn %g1, .BB0
! CHECK: movrz %g1, %g2, %g3 ! encoding: [0x87,0x78,0x44,0x02]
! CHECK: movrlez %g1, %g2, %g3 ! encoding: [0x87,0x78,0x48,0x02]
! CHECK: movrlz %g1, %g2, %g3 ! encoding: [0x87,0x78,0x4c,0x02]
! CHECK: movrnz %g1, %g2, %g3 ! encoding: [0x87,0x78,0x54,0x02]
! CHECK: movrgz %g1, %g2, %g3 ! encoding: [0x87,0x78,0x58,0x02]
! CHECK: movrgez %g1, %g2, %g3 ! encoding: [0x87,0x78,0x5c,0x02]
movrz %g1, %g2, %g3
movrlez %g1, %g2, %g3
movrlz %g1, %g2, %g3
movrnz %g1, %g2, %g3
movrgz %g1, %g2, %g3
movrgez %g1, %g2, %g3
! CHECK: fmovrsz %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x44,0xa2]
! CHECK: fmovrslez %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x48,0xa2]
! CHECK: fmovrslz %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x4c,0xa2]
! CHECK: fmovrsnz %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x54,0xa2]
! CHECK: fmovrsgz %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x58,0xa2]
! CHECK: fmovrsgez %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x5c,0xa2]
fmovrsz %g1, %f2, %f3
fmovrslez %g1, %f2, %f3
fmovrslz %g1, %f2, %f3
fmovrsnz %g1, %f2, %f3
fmovrsgz %g1, %f2, %f3
fmovrsgez %g1, %f2, %f3