Index: llvm/lib/Target/Xtensa/CMakeLists.txt =================================================================== --- llvm/lib/Target/Xtensa/CMakeLists.txt +++ llvm/lib/Target/Xtensa/CMakeLists.txt @@ -1,5 +1,12 @@ add_llvm_component_group(Xtensa) +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 +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// 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<(all_of 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,218 @@ +//===- XtensaInstrFormats.td - Xtensa Instruction Formats --*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// 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; + + 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> { + let isPseudo = 1; + let isCodeGenOnly = 1; +} Index: llvm/lib/Target/Xtensa/XtensaInstrInfo.td =================================================================== --- /dev/null +++ llvm/lib/Target/Xtensa/XtensaInstrInfo.td @@ -0,0 +1,152 @@ +//===- XtensaInstrInfo.td - Target Description for Xtensa -*- tablegen -*--===// +// +// The LLVM Compiler Infrastructure +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// 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; +} + +def EXTW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "extw", []> { + let r = 0x2; + let s = 0x0; + let t = 0xd; + let hasSideEffects = 1; +} + +//===----------------------------------------------------------------------===// +// Processor control instructions +//===----------------------------------------------------------------------===// + +def DSYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "dsync", []> { + let r = 0x2; + let s = 0x0; + let t = 0x3; + let hasSideEffects = 1; +} + +def ISYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "isync", []> { + let r = 0x2; + let s = 0x0; + let t = 0x0; + let hasSideEffects = 1; +} + +def RSYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "rsync", []> { + let r = 0x2; + let s = 0x0; + let t = 0x1; + let hasSideEffects = 1; +} + +def ESYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), + "esync", []> { + let r = 0x2; + let s = 0x0; + let t = 0x2; + let hasSideEffects = 1; +} + +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,32 @@ +//===- XtensaOperands.td - Xtensa instruction operands -------*- tblgen-*--===// +// +// The LLVM Compiler Infrastructure +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// 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 +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// 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)>;