[Sparc] Make SPARC instructions' encoding well defined such that TableGen can automatically generate code emitter.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191168 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Venkatraman Govindaraju 2013-09-22 09:54:42 +00:00
parent 69ae8f1abd
commit 0821c72f11
4 changed files with 70 additions and 39 deletions

View File

@ -2,6 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td)
tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter)
tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM SparcGenSubtargetInfo.inc -gen-subtarget)

View File

@ -14,7 +14,8 @@ TARGET = Sparc
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \
SparcGenAsmWriter.inc SparcGenDAGISel.inc \
SparcGenSubtargetInfo.inc SparcGenCallingConv.inc
SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
SparcGenCodeEmitter.inc
DIRS = TargetInfo MCTargetDesc

View File

@ -111,6 +111,32 @@ class F3_3<bits<2> opVal, bits<6> op3val, bits<9> opfval, dag outs, dag ins,
let Inst{4-0} = rs2;
}
// floating-point unary operations.
class F3_3u<bits<2> opVal, bits<6> op3val, bits<9> opfval, dag outs, dag ins,
string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
bits<5> rs2;
let op = opVal;
let op3 = op3val;
let rs1 = 0;
let Inst{13-5} = opfval; // fp opcode
let Inst{4-0} = rs2;
}
// floating-point compares.
class F3_3c<bits<2> opVal, bits<6> op3val, bits<9> opfval, dag outs, dag ins,
string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
bits<5> rs2;
let op = opVal;
let op3 = op3val;
let rd = 0;
let Inst{13-5} = opfval; // fp opcode
let Inst{4-0} = rs2;
}
// Shift by register rs2.
class F3_Sr<bits<2> opVal, bits<6> op3val, bit xVal, dag outs, dag ins,
string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {

View File

@ -259,8 +259,9 @@ let hasSideEffects = 1, mayStore = 1 in {
[(flushw)]>;
}
def UNIMP : F2_1<0b000, (outs), (ins i32imm:$val),
"unimp $val", []>;
let rd = 0 in
def UNIMP : F2_1<0b000, (outs), (ins i32imm:$val),
"unimp $val", []>;
// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after
// instruction selection into a branch sequence. This has to handle all
@ -511,9 +512,10 @@ defm SUB : F3_12 <"sub" , 0b000100, sub>;
let Uses = [ICC] in
defm SUBX : F3_12 <"subx" , 0b001100, sube>;
let Defs = [ICC] in {
let Defs = [ICC] in
defm SUBCC : F3_12 <"subcc", 0b010100, subc>;
let Defs = [ICC], rd = 0 in {
def CMPrr : F3_1<2, 0b010100,
(outs), (ins IntRegs:$b, IntRegs:$c),
"cmp $b, $c",
@ -571,7 +573,7 @@ class BranchSP<dag ins, string asmstr, list<dag> pattern>
// Indirect branch instructions.
let isTerminator = 1, isBarrier = 1,
hasDelaySlot = 1, isBranch =1,
isIndirectBranch = 1 in {
isIndirectBranch = 1, rd = 0 in {
def BINDrr : F3_1<2, 0b111000,
(outs), (ins MEMrr:$ptr),
"jmp $ptr",
@ -618,21 +620,21 @@ let Uses = [O6],
def JMPLrr : F3_1<2, 0b111000,
(outs), (ins MEMrr:$ptr, variable_ops),
"call $ptr",
[(call ADDRrr:$ptr)]>;
[(call ADDRrr:$ptr)]> { let rd = 15; }
def JMPLri : F3_2<2, 0b111000,
(outs), (ins MEMri:$ptr, variable_ops),
"call $ptr",
[(call ADDRri:$ptr)]>;
[(call ADDRri:$ptr)]> { let rd = 15; }
}
// Section B.28 - Read State Register Instructions
let Uses = [Y] in
let Uses = [Y], rs1 = 0, rs2 = 0 in
def RDY : F3_1<2, 0b101000,
(outs IntRegs:$dst), (ins),
"rd %y, $dst", []>;
// Section B.29 - Write State Register Instructions
let Defs = [Y] in {
let Defs = [Y], rd = 0 in {
def WRYrr : F3_1<2, 0b110000,
(outs), (ins IntRegs:$b, IntRegs:$c),
"wr $b, $c, %y", []>;
@ -641,89 +643,89 @@ let Defs = [Y] in {
"wr $b, $c, %y", []>;
}
// Convert Integer to Floating-point Instructions, p. 141
def FITOS : F3_3<2, 0b110100, 0b011000100,
def FITOS : F3_3u<2, 0b110100, 0b011000100,
(outs FPRegs:$dst), (ins FPRegs:$src),
"fitos $src, $dst",
[(set FPRegs:$dst, (SPitof FPRegs:$src))]>;
def FITOD : F3_3<2, 0b110100, 0b011001000,
def FITOD : F3_3u<2, 0b110100, 0b011001000,
(outs DFPRegs:$dst), (ins FPRegs:$src),
"fitod $src, $dst",
[(set DFPRegs:$dst, (SPitof FPRegs:$src))]>;
def FITOQ : F3_3<2, 0b110100, 0b011001100,
def FITOQ : F3_3u<2, 0b110100, 0b011001100,
(outs QFPRegs:$dst), (ins FPRegs:$src),
"fitoq $src, $dst",
[(set QFPRegs:$dst, (SPitof FPRegs:$src))]>,
Requires<[HasHardQuad]>;
// Convert Floating-point to Integer Instructions, p. 142
def FSTOI : F3_3<2, 0b110100, 0b011010001,
def FSTOI : F3_3u<2, 0b110100, 0b011010001,
(outs FPRegs:$dst), (ins FPRegs:$src),
"fstoi $src, $dst",
[(set FPRegs:$dst, (SPftoi FPRegs:$src))]>;
def FDTOI : F3_3<2, 0b110100, 0b011010010,
def FDTOI : F3_3u<2, 0b110100, 0b011010010,
(outs FPRegs:$dst), (ins DFPRegs:$src),
"fdtoi $src, $dst",
[(set FPRegs:$dst, (SPftoi DFPRegs:$src))]>;
def FQTOI : F3_3<2, 0b110100, 0b011010011,
def FQTOI : F3_3u<2, 0b110100, 0b011010011,
(outs FPRegs:$dst), (ins QFPRegs:$src),
"fqtoi $src, $dst",
[(set FPRegs:$dst, (SPftoi QFPRegs:$src))]>,
Requires<[HasHardQuad]>;
// Convert between Floating-point Formats Instructions, p. 143
def FSTOD : F3_3<2, 0b110100, 0b011001001,
def FSTOD : F3_3u<2, 0b110100, 0b011001001,
(outs DFPRegs:$dst), (ins FPRegs:$src),
"fstod $src, $dst",
[(set f64:$dst, (fextend f32:$src))]>;
def FSTOQ : F3_3<2, 0b110100, 0b011001101,
def FSTOQ : F3_3u<2, 0b110100, 0b011001101,
(outs QFPRegs:$dst), (ins FPRegs:$src),
"fstoq $src, $dst",
[(set f128:$dst, (fextend f32:$src))]>,
Requires<[HasHardQuad]>;
def FDTOS : F3_3<2, 0b110100, 0b011000110,
def FDTOS : F3_3u<2, 0b110100, 0b011000110,
(outs FPRegs:$dst), (ins DFPRegs:$src),
"fdtos $src, $dst",
[(set f32:$dst, (fround f64:$src))]>;
def FDTOQ : F3_3<2, 0b110100, 0b01101110,
def FDTOQ : F3_3u<2, 0b110100, 0b01101110,
(outs QFPRegs:$dst), (ins DFPRegs:$src),
"fdtoq $src, $dst",
[(set f128:$dst, (fextend f64:$src))]>,
Requires<[HasHardQuad]>;
def FQTOS : F3_3<2, 0b110100, 0b011000111,
def FQTOS : F3_3u<2, 0b110100, 0b011000111,
(outs FPRegs:$dst), (ins QFPRegs:$src),
"fqtos $src, $dst",
[(set f32:$dst, (fround f128:$src))]>,
Requires<[HasHardQuad]>;
def FQTOD : F3_3<2, 0b110100, 0b011001011,
def FQTOD : F3_3u<2, 0b110100, 0b011001011,
(outs DFPRegs:$dst), (ins QFPRegs:$src),
"fqtod $src, $dst",
[(set f64:$dst, (fround f128:$src))]>,
Requires<[HasHardQuad]>;
// Floating-point Move Instructions, p. 144
def FMOVS : F3_3<2, 0b110100, 0b000000001,
def FMOVS : F3_3u<2, 0b110100, 0b000000001,
(outs FPRegs:$dst), (ins FPRegs:$src),
"fmovs $src, $dst", []>;
def FNEGS : F3_3<2, 0b110100, 0b000000101,
def FNEGS : F3_3u<2, 0b110100, 0b000000101,
(outs FPRegs:$dst), (ins FPRegs:$src),
"fnegs $src, $dst",
[(set f32:$dst, (fneg f32:$src))]>;
def FABSS : F3_3<2, 0b110100, 0b000001001,
def FABSS : F3_3u<2, 0b110100, 0b000001001,
(outs FPRegs:$dst), (ins FPRegs:$src),
"fabss $src, $dst",
[(set f32:$dst, (fabs f32:$src))]>;
// Floating-point Square Root Instructions, p.145
def FSQRTS : F3_3<2, 0b110100, 0b000101001,
def FSQRTS : F3_3u<2, 0b110100, 0b000101001,
(outs FPRegs:$dst), (ins FPRegs:$src),
"fsqrts $src, $dst",
[(set f32:$dst, (fsqrt f32:$src))]>;
def FSQRTD : F3_3<2, 0b110100, 0b000101010,
def FSQRTD : F3_3u<2, 0b110100, 0b000101010,
(outs DFPRegs:$dst), (ins DFPRegs:$src),
"fsqrtd $src, $dst",
[(set f64:$dst, (fsqrt f64:$src))]>;
def FSQRTQ : F3_3<2, 0b110100, 0b000101011,
def FSQRTQ : F3_3u<2, 0b110100, 0b000101011,
(outs QFPRegs:$dst), (ins QFPRegs:$src),
"fsqrtq $src, $dst",
[(set f128:$dst, (fsqrt f128:$src))]>,
@ -808,15 +810,15 @@ def FDIVQ : F3_3<2, 0b110100, 0b001001111,
// after the instr is retired, but there is no interlock. This behavior
// is modelled with a forced noop after the instruction.
let Defs = [FCC] in {
def FCMPS : F3_3<2, 0b110101, 0b001010001,
def FCMPS : F3_3c<2, 0b110101, 0b001010001,
(outs), (ins FPRegs:$src1, FPRegs:$src2),
"fcmps $src1, $src2\n\tnop",
[(SPcmpfcc f32:$src1, f32:$src2)]>;
def FCMPD : F3_3<2, 0b110101, 0b001010010,
def FCMPD : F3_3c<2, 0b110101, 0b001010010,
(outs), (ins DFPRegs:$src1, DFPRegs:$src2),
"fcmpd $src1, $src2\n\tnop",
[(SPcmpfcc f64:$src1, f64:$src2)]>;
def FCMPQ : F3_3<2, 0b110101, 0b001010011,
def FCMPQ : F3_3c<2, 0b110101, 0b001010011,
(outs), (ins QFPRegs:$src1, QFPRegs:$src2),
"fcmpq $src1, $src2\n\tnop",
[(SPcmpfcc f128:$src1, f128:$src2)]>,
@ -927,27 +929,27 @@ let Predicates = [HasV9], Constraints = "$f = $rd" in {
// Floating-Point Move Instructions, p. 164 of the V9 manual.
let Predicates = [HasV9] in {
def FMOVD : F3_3<2, 0b110100, 0b000000010,
def FMOVD : F3_3u<2, 0b110100, 0b000000010,
(outs DFPRegs:$dst), (ins DFPRegs:$src),
"fmovd $src, $dst", []>;
def FMOVQ : F3_3<2, 0b110100, 0b000000011,
def FMOVQ : F3_3u<2, 0b110100, 0b000000011,
(outs QFPRegs:$dst), (ins QFPRegs:$src),
"fmovq $src, $dst", []>,
Requires<[HasHardQuad]>;
def FNEGD : F3_3<2, 0b110100, 0b000000110,
def FNEGD : F3_3u<2, 0b110100, 0b000000110,
(outs DFPRegs:$dst), (ins DFPRegs:$src),
"fnegd $src, $dst",
[(set f64:$dst, (fneg f64:$src))]>;
def FNEGQ : F3_3<2, 0b110100, 0b000000111,
def FNEGQ : F3_3u<2, 0b110100, 0b000000111,
(outs QFPRegs:$dst), (ins QFPRegs:$src),
"fnegq $src, $dst",
[(set f128:$dst, (fneg f128:$src))]>,
Requires<[HasHardQuad]>;
def FABSD : F3_3<2, 0b110100, 0b000001010,
def FABSD : F3_3u<2, 0b110100, 0b000001010,
(outs DFPRegs:$dst), (ins DFPRegs:$src),
"fabsd $src, $dst",
[(set f64:$dst, (fabs f64:$src))]>;
def FABSQ : F3_3<2, 0b110100, 0b000001011,
def FABSQ : F3_3u<2, 0b110100, 0b000001011,
(outs QFPRegs:$dst), (ins QFPRegs:$src),
"fabsq $src, $dst",
[(set f128:$dst, (fabs f128:$src))]>,
@ -956,9 +958,10 @@ let Predicates = [HasV9] in {
// POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear
// the top 32-bits before using it. To do this clearing, we use a SLLri X,0.
def POPCrr : F3_1<2, 0b101110,
(outs IntRegs:$dst), (ins IntRegs:$src),
"popc $src, $dst", []>, Requires<[HasV9]>;
let rs1 = 0 in
def POPCrr : F3_1<2, 0b101110,
(outs IntRegs:$dst), (ins IntRegs:$src),
"popc $src, $dst", []>, Requires<[HasV9]>;
def : Pat<(ctpop i32:$src),
(POPCrr (SLLri $src, 0))>;