Index: llvm/lib/Target/Xtensa/CMakeLists.txt =================================================================== --- llvm/lib/Target/Xtensa/CMakeLists.txt +++ llvm/lib/Target/Xtensa/CMakeLists.txt @@ -1,3 +1,10 @@ +set(LLVM_TARGET_DEFINITIONS Xtensa.td) + +tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info) +tablegen(LLVM XtensaGenRegisterInfo.inc -gen-register-info) + +add_public_tablegen_target(XtensaCommonTableGen) + add_llvm_target(XtensaCodeGen XtensaTargetMachine.cpp ) Index: llvm/lib/Target/Xtensa/Xtensa.td =================================================================== --- /dev/null +++ llvm/lib/Target/Xtensa/Xtensa.td @@ -0,0 +1,52 @@ +//===- Xtensa.td - Describe the Xtensa Target Machine -----------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Target-independent interfaces +//===----------------------------------------------------------------------===// + +include "llvm/Target/Target.td" + +//===----------------------------------------------------------------------===// +// Subtarget Features. +//===----------------------------------------------------------------------===// +def FeatureDensity : SubtargetFeature<"density", "HasDensity", "true", + "Enable Density instructions">; +def HasDensity : Predicate<"Subtarget->hasDensity()">, + AssemblerPredicate<"FeatureDensity">; +//===----------------------------------------------------------------------===// +// Xtensa supported processors. +//===----------------------------------------------------------------------===// +class Proc Features> + : Processor; + +def : Proc<"generic", []>; + +//===----------------------------------------------------------------------===// +// Register File Description +//===----------------------------------------------------------------------===// + +include "XtensaRegisterInfo.td" + +//===----------------------------------------------------------------------===// +// Instruction Descriptions +//===----------------------------------------------------------------------===// + +include "XtensaInstrInfo.td" + +def XtensaInstrInfo : InstrInfo; + +//===----------------------------------------------------------------------===// +// Target Declaration +//===----------------------------------------------------------------------===// + +def Xtensa : Target +{ + let InstructionSet = XtensaInstrInfo; +} Index: llvm/lib/Target/Xtensa/XtensaInstrFormats.td =================================================================== --- /dev/null +++ llvm/lib/Target/Xtensa/XtensaInstrFormats.td @@ -0,0 +1,237 @@ +//===- XtensaInstrFormats.td - Xtensa Instruction Formats -------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------------===// + +// Base class for Xtensa 16 & 24 bit Formats +class XtensaInst pattern, + InstrItinClass itin = NoItinerary>: Instruction +{ + let Namespace = "Xtensa"; + + let Size = size; + + let OutOperandList = outs; + let InOperandList = ins; + + let AsmString = asmstr; + let Pattern = pattern; + let Itinerary = itin; + +} + +// Base class for Xtensa 24 bit Format +class XtensaInst24 pattern, + InstrItinClass itin = NoItinerary>: + XtensaInst<3, outs, ins, asmstr, pattern, itin> +{ + field bits<24> Inst; + field bits<24> SoftFail = 0; +} + +// Base class for Xtensa 16 bit Format +class XtensaInst16 pattern, + InstrItinClass itin = NoItinerary>: + XtensaInst<2, outs, ins, asmstr, pattern, itin> +{ + field bits<16> Inst; + field bits<16> SoftFail = 0; + let Predicates = [HasDensity]; +} + +class RRR_Inst op0, bits<4> op1, bits<4> op2, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst24 +{ + bits<4> r; + bits<4> s; + bits<4> t; + //bits<4> op2; + + let Inst{23-20} = op2; + let Inst{19-16} = op1; + let Inst{15-12} = r; + let Inst{11-8} = s; + let Inst{7-4} = t; + let Inst{3-0} = op0; +} + +class RRI4_Inst op0, bits<4> op1, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst24 +{ + bits<4> r; + bits<4> s; + bits<4> t; + bits<4> imm4; + + let Inst{23-20} = imm4; + let Inst{19-16} = op1; + let Inst{15-12} = r; + let Inst{11-8} = s; + let Inst{7-4} = t; + let Inst{3-0} = op0; +} + +class RRI8_Inst op0, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst24 +{ + bits<4> r; + bits<4> s; + bits<4> t; + bits<8> imm8; + + let Inst{23-16} = imm8; + let Inst{15-12} = r; + let Inst{11-8} = s; + let Inst{7-4} = t; + let Inst{3-0} = op0; +} + +class RI16_Inst op0, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst24 +{ + bits<4> t; + bits<16> imm16; + + let Inst{23-8} = imm16; + let Inst{7-4} = t; + let Inst{3-0} = op0; +} + +class RSR_Inst op0, bits<4> op1, bits<4> op2, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst24 +{ + bits<8> sr; + bits<4> t; + + let Inst{23-20} = op2; + let Inst{19-16} = op1; + let Inst{15-8} = sr; + let Inst{7-4} = t; + let Inst{3-0} = op0; +} + +class CALL_Inst op0, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst24 +{ + bits<18> offset; + bits<2> n; + + let Inst{23-6} = offset; + let Inst{5-4} = n; + let Inst{3-0} = op0; +} + +class CALLX_Inst op0, bits<4> op1, bits<4> op2, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst24 +{ + bits<4> r; + bits<4> s; + bits<2> m; + bits<2> n; + + let Inst{23-20} = op2; + let Inst{19-16} = op1; + let Inst{15-12} = r; + let Inst{11-8} = s; + let Inst{7-6} = m; + let Inst{5-4} = n; + let Inst{3-0} = op0; +} + +class BRI8_Inst op0, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst24 +{ + bits<8> imm8; + bits<4> r; + bits<4> s; + bits<2> m; + bits<2> n; + + let Inst{23-16} = imm8; + let Inst{15-12} = r; + let Inst{11-8} = s; + let Inst{7-6} = m; + let Inst{5-4} = n; + let Inst{3-0} = op0; +} + +class BRI12_Inst op0, bits<2> n, bits<2> m, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst24 +{ + bits<12> imm12; + bits<4> s; + + + let Inst{23-12} = imm12; + let Inst{11-8} = s; + let Inst{7-6} = m; + let Inst{5-4} = n; + let Inst{3-0} = op0; +} + +class RRRN_Inst op0, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst16 +{ + bits<4> r; + bits<4> s; + bits<4> t; + + let Inst{15-12} = r; + let Inst{11-8} = s; + let Inst{7-4} = t; + let Inst{3-0} = op0; +} + +class RI7_Inst op0, bits<1> i, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst16 +{ + bits<7> imm7; + bits<4> s; + + let Inst{15-12} = imm7{3-0}; + let Inst{11-8} = s; + let Inst{7} = i; + let Inst{6-4} = imm7{6-4}; + let Inst{3-0} = op0; +} + +class RI6_Inst op0, bits<1> i, bits<1> z, dag outs, dag ins, + string asmstr, list pattern, InstrItinClass itin = NoItinerary>: + XtensaInst16 +{ + bits<6> imm6; + bits<4> s; + + let Inst{15-12} = imm6{3-0}; + let Inst{11-8} = s; + let Inst{7} = i; + let Inst{6} = z; + let Inst{5-4} = imm6{5-4}; + let Inst{3-0} = op0; +} + +// Pseudo instructions +class Pseudo pattern> + : XtensaInst<2, outs, ins, asmstr, pattern> +{ + field bits<16> Inst; + field bits<16> SoftFail = 0; + let Inst = 0x0; + let isPseudo = 1; + let isCodeGenOnly = 1; +} Index: llvm/lib/Target/Xtensa/XtensaInstrInfo.td =================================================================== --- /dev/null +++ llvm/lib/Target/Xtensa/XtensaInstrInfo.td @@ -0,0 +1,160 @@ +//===- XtensaInstrInfo.td - Target Description for Xtensa Target -*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------------===// +// +// This file describes the Xtensa instructions in TableGen format. +// +//===----------------------------------------------------------------------------===// + +include "XtensaInstrFormats.td" +include "XtensaOperands.td" + +//===----------------------------------------------------------------------===// +// Arithmetic & Logical instructions +//===----------------------------------------------------------------------===// + +class ArithLogic_RRR oper2, bits<4> oper1, string instrAsm, + SDPatternOperator opNode, bit isComm = 0> + : RRR_Inst<0x00, oper1, oper2, (outs AR:$r), (ins AR:$s, AR:$t), + instrAsm#"\t$r, $s, $t", + [(set AR:$r, (opNode AR:$s, AR:$t))]> +{ + let isCommutable = isComm; + let isReMaterializable = 0; +} + +def ADD: ArithLogic_RRR<0x08, 0x00, "add", add, 1>; +def SUB: ArithLogic_RRR<0x0C, 0x00, "sub", sub>; +def AND: ArithLogic_RRR<0x01, 0x00, "and", and, 1>; +def OR: ArithLogic_RRR<0x02, 0x00, "or", or, 1>; +def XOR: ArithLogic_RRR<0x03, 0x00, "xor", xor, 1>; + +class ADDX oper, string instrAsm, list pattern> + : RRR_Inst<0x00, 0x00, oper, (outs AR:$r), (ins AR:$s, AR:$t), + instrAsm#"\t$r, $s, $t", pattern>; + +def ADDX2: ADDX<0x09, "addx2", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 1))))]>; +def ADDX4: ADDX<0x0A, "addx4", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 2))))]>; +def ADDX8: ADDX<0x0B, "addx8", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 3))))]>; + +class SUBX oper, string instrAsm, list pattern> + : RRR_Inst<0x00, 0x00, oper, (outs AR:$r), (ins AR:$s, AR:$t), + instrAsm#"\t$r, $s, $t", pattern>; + +def SUBX2: SUBX<0x0D, "subx2", [(set AR:$r, (sub (shl AR:$s, (i32 1)), AR:$t))]>; +def SUBX4: SUBX<0x0E, "subx4", [(set AR:$r, (sub (shl AR:$s, (i32 2)), AR:$t))]>; +def SUBX8: SUBX<0x0F, "subx8", [(set AR:$r, (sub (shl AR:$s, (i32 3)), AR:$t))]>; + +def ABS: RRR_Inst<0x00, 0x00, 0x06, (outs AR:$r), (ins AR:$t), + "abs\t$r, $t", []> +{ + let s = 0x1; +} + +def ADDI: RRI8_Inst<0x02, (outs AR:$t), (ins AR:$s, imm8:$imm8), + "addi\t$t, $s, $imm8", + [(set AR:$t, (add AR:$s, imm8:$imm8))]> +{ + let r = 0x0C; +} + +def ADDMI: RRI8_Inst<0x02, (outs AR:$t), (ins AR:$s, imm8_sh8:$imm_sh8), + "addmi\t$t, $s, $imm_sh8", + [(set AR:$t, (add AR:$s, imm8_sh8:$imm_sh8))]> +{ + bits<16> imm_sh8; + + let r = 0x0D; + let imm8 = imm_sh8{15-8}; +} + +def NEG: RRR_Inst<0x00, 0x00, 0x06, (outs AR:$r), (ins AR:$t), + "neg\t$r, $t", + [(set AR:$r, (ineg AR:$t))]> +{ + let s = 0x00; +} + +//===----------------------------------------------------------------------===// +// Move instructions +//===----------------------------------------------------------------------===// + +// Conditional move +def MOVEQZ : RRR_Inst<0x00, 0x03, 0x08, (outs AR:$r), (ins AR:$s, AR:$t), + "moveqz\t$r, $s, $t", []>; +def MOVNEZ : RRR_Inst<0x00, 0x03, 0x09, (outs AR:$r), (ins AR:$s, AR:$t), + "movnez\t$r, $s, $t", []>; +def MOVLTZ : RRR_Inst<0x00, 0x03, 0x0A, (outs AR:$r), (ins AR:$s, AR:$t), + "movltz\t$r, $s, $t", []>; +def MOVGEZ : RRR_Inst<0x00, 0x03, 0x0B, (outs AR:$r), (ins AR:$s, AR:$t), + "movgez\t$r, $s, $t", []>; + +//===----------------------------------------------------------------------===// +// Mem barrier instructions +//===----------------------------------------------------------------------===// +def MEMW: RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "memw", []> +{ + let r = 0x2; + let t = 0x0c; + let s = 0x0; + let hasSideEffects = 1; +} + +def EXTW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "extw", []> +{ + let r = 0x2; + let s = 0x0; + let t = 0xd; +} + +//===----------------------------------------------------------------------===// +// Processor control instructions +//===----------------------------------------------------------------------===// + +def DSYNC: RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "dsync", []> +{ + let r = 0x2; + let s = 0x0; + let t = 0x3; +} + +def ISYNC: RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "isync", []> +{ + let r = 0x2; + let s = 0x0; + let t = 0x0; +} + +def RSYNC: RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "rsync", []> +{ + let r = 0x2; + let s = 0x0; + let t = 0x1; +} + +def ESYNC: RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "esync", []> +{ + let r = 0x2; + let s = 0x0; + let t = 0x2; +} + +def NOP: RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "nop", + []> +{ + let r = 0x02; + let s = 0x00; + let t = 0x0f; +} Index: llvm/lib/Target/Xtensa/XtensaOperands.td =================================================================== --- /dev/null +++ llvm/lib/Target/Xtensa/XtensaOperands.td @@ -0,0 +1,35 @@ +//===- XtensaOperands.td - Xtensa instruction operands ----*- tblgen-*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===-------------------------------------------------------------------===// + +// Immediate operands with a shared generic render method. +class ImmAsmOperand : AsmOperandClass +{ + let Name = name; + let RenderMethod = "addImmOperands"; + let DiagnosticType = !strconcat("Invalid", name); +} + +class Immediate + : Operand, ImmLeaf +{ + let PrintMethod = "print"##asmop; + let ParserMatchClass = !cast(asmop); +} + +// imm8 predicate - Immediate in the range [-128,127] +def Imm8_AsmOperand: ImmAsmOperand<"Imm8">; +def imm8: Immediate= -128 && Imm <= 127; }], "Imm8_AsmOperand"> { +} + +// imm8_sh8 predicate - Immediate in the range [-32768,32512] with (bits[7-0] == 0) +// imm8 value left shifted by 8 bits +def Imm8_sh8_AsmOperand: ImmAsmOperand<"Imm8_sh8">; +def imm8_sh8: Immediate= -32768 && Imm <= 32512 && ((Imm & 0xFF) == 0); }], "Imm8_sh8_AsmOperand"> { + +} Index: llvm/lib/Target/Xtensa/XtensaRegisterInfo.td =================================================================== --- /dev/null +++ llvm/lib/Target/Xtensa/XtensaRegisterInfo.td @@ -0,0 +1,78 @@ +//===- XtensaRegisterInfo.td - Xtensa Register defs -----------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===-------------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Class definitions. +//===----------------------------------------------------------------------===// + +class XtensaReg : Register { + let Namespace = "Xtensa"; +} + +class XtensaRegWithSubRegs subregs> + : RegisterWithSubRegs { + let Namespace = "Xtensa"; +} + +//===----------------------------------------------------------------------===// +// General-purpose registers +//===----------------------------------------------------------------------===// + +// Xtensa general purpose regs +class ARReg num, string n, list alt = []> : XtensaReg { + let HWEncoding{3-0} = num; + let AltNames = alt; +} + +// Return Address +def a0 : ARReg<0, "a0">, DwarfRegNum<[0]>; + +// Stack Pointer (callee-saved) +def sp : ARReg<1, "a1", ["sp"]>, DwarfRegNum<[1]>; + +// Function Arguments +def a2 : ARReg<2, "a2">, DwarfRegNum<[2]>; +def a3 : ARReg<3, "a3">, DwarfRegNum<[3]>; +def a4 : ARReg<4, "a4">, DwarfRegNum<[4]>; +def a5 : ARReg<5, "a5">, DwarfRegNum<[5]>; +def a6 : ARReg<6, "a6">, DwarfRegNum<[6]>; +def a7 : ARReg<7, "a7">, DwarfRegNum<[7]>; + +// Static Chain +def a8 : ARReg<8, "a8">, DwarfRegNum<[8]>; + +def a9 : ARReg<9, "a9">, DwarfRegNum<[9]>; +def a10 : ARReg<10, "a10">, DwarfRegNum<[10]>; +def a11 : ARReg<11, "a11">, DwarfRegNum<[11]>; + +// Callee-saved +def a12 : ARReg<12, "a12">, DwarfRegNum<[12]>; +def a13 : ARReg<13, "a13">, DwarfRegNum<[13]>; +def a14 : ARReg<14, "a14">, DwarfRegNum<[14]>; + +// Stack-Frame Pointer (optional) - Callee-Saved +def a15 : ARReg<15, "a15">, DwarfRegNum<[15]>; + +// Register class with allocation order +def AR : RegisterClass<"Xtensa", [i32], 32, (add + a8, a9, a10, a11, a12, a13, a14, a15, + a7, a6, a5, a4, a3, a2, a0, sp)>; +//===----------------------------------------------------------------------===// +// Special-purpose registers +//===----------------------------------------------------------------------===// +class SRReg num, string n, list alt = []> : XtensaReg { + let HWEncoding{7-0} = num; + let AltNames = alt; +} + +// Shift Amount Register +def sar : SRReg<3, "sar", ["SAR","3"]>; + +def SR : RegisterClass<"Xtensa", [i32], 32, (add sar)>; +