Add initial Xtensa.td file with target machine description. Add XtensaInstrInfo.td,
currently describe just susbet of Core Instructions like ALU, Processor control,
memory barrier and some move instructions. Add descriptions of the instructions
formats(XtensaInstrInfo.td) and some immediate instruction operands(XtensaOperands.td).
Add General Registers and Special Registers classes.
Differential Revision: https://reviews.llvm.org/D64830
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
--- /dev/null
+//===- 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<string Name, list<SubtargetFeature> Features>
+ : Processor<Name, NoItineraries, Features>;
+
+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;
+}
--- /dev/null
+//===- 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<int size, dag outs, dag ins, string asmstr, list<dag> 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<dag outs, dag ins, string asmstr, list<dag> 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<dag outs, dag ins, string asmstr, list<dag> 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<bits<4> op0, bits<4> op1, bits<4> op2, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst24<outs, ins, asmstr, pattern, itin> {
+ 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<bits<4> op0, bits<4> op1, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst24<outs, ins, asmstr, pattern, itin> {
+ 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<bits<4> op0, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst24<outs, ins, asmstr, pattern, itin> {
+ 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<bits<4> op0, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst24<outs, ins, asmstr, pattern, itin> {
+ bits<4> t;
+ bits<16> imm16;
+
+ let Inst{23-8} = imm16;
+ let Inst{7-4} = t;
+ let Inst{3-0} = op0;
+}
+
+class RSR_Inst<bits<4> op0, bits<4> op1, bits<4> op2, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst24<outs, ins, asmstr, pattern, itin> {
+ 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<bits<4> op0, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst24<outs, ins, asmstr, pattern, itin> {
+ bits<18> offset;
+ bits<2> n;
+
+ let Inst{23-6} = offset;
+ let Inst{5-4} = n;
+ let Inst{3-0} = op0;
+}
+
+class CALLX_Inst<bits<4> op0, bits<4> op1, bits<4> op2, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst24<outs, ins, asmstr, pattern, itin> {
+ 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<bits<4> op0, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst24<outs, ins, asmstr, pattern, itin> {
+ 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<bits<4> op0, bits<2> n, bits<2> m, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst24<outs, ins, asmstr, pattern, itin> {
+ 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<bits<4> op0, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst16<outs, ins, asmstr, pattern, itin> {
+ 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<bits<4> op0, bits<1> i, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst16<outs, ins, asmstr, pattern, itin> {
+ 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<bits<4> op0, bits<1> i, bits<1> z, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+ : XtensaInst16<outs, ins, asmstr, pattern, itin> {
+ 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<dag outs, dag ins, string asmstr, list<dag> pattern>
+ : XtensaInst<2, outs, ins, asmstr, pattern> {
+ let isPseudo = 1;
+ let isCodeGenOnly = 1;
+}
--- /dev/null
+//===- 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<bits<4> 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<bits<4> oper, string instrAsm, list<dag> 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<bits<4> oper, string instrAsm, list<dag> 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;
+}
--- /dev/null
+//===- 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<string name> : AsmOperandClass {
+ let Name = name;
+ let RenderMethod = "addImmOperands";
+ let DiagnosticType = !strconcat("Invalid", name);
+}
+
+class Immediate<ValueType vt, code pred, string asmop>
+ : Operand<vt>, ImmLeaf<vt, pred> {
+ let PrintMethod = "print"#asmop;
+ let ParserMatchClass = !cast<AsmOperandClass>(asmop);
+}
+
+// imm8 predicate - Immediate in the range [-128,127]
+def Imm8_AsmOperand : ImmAsmOperand<"Imm8">;
+def imm8 : Immediate<i32, [{ return Imm >= -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<i32, [{ return Imm >= -32768 && Imm <= 32512 && ((Imm & 0xFF) == 0); }],
+ "Imm8_sh8_AsmOperand">;
--- /dev/null
+//===- 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<string n> : Register<n> {
+ let Namespace = "Xtensa";
+}
+
+class XtensaRegWithSubRegs<string n, list<Register> subregs>
+ : RegisterWithSubRegs<n, subregs> {
+ let Namespace = "Xtensa";
+}
+
+//===----------------------------------------------------------------------===//
+// General-purpose registers
+//===----------------------------------------------------------------------===//
+
+// Xtensa general purpose regs
+class ARReg<bits<4> num, string n, list<string> alt = []> : XtensaReg<n> {
+ 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<bits<8> num, string n, list<string> alt = []> : XtensaReg<n> {
+ 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)>;