mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-14 09:38:40 +00:00
[Mips][msa] Added initial MSA support.
* msa SubtargetFeature * registers * ld.[bhwd], and st.[bhwd] instructions Does not correctly prohibit use of both 32-bit FPU registers and MSA together. Patch by Daniel Sanders git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188313 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
da0860f78e
commit
3f70e908c3
@ -78,6 +78,8 @@ def FeatureDSP : SubtargetFeature<"dsp", "HasDSP", "true", "Mips DSP ASE">;
|
|||||||
def FeatureDSPR2 : SubtargetFeature<"dspr2", "HasDSPR2", "true",
|
def FeatureDSPR2 : SubtargetFeature<"dspr2", "HasDSPR2", "true",
|
||||||
"Mips DSP-R2 ASE", [FeatureDSP]>;
|
"Mips DSP-R2 ASE", [FeatureDSP]>;
|
||||||
|
|
||||||
|
def FeatureMSA : SubtargetFeature<"msa", "HasMSA", "true", "Mips MSA ASE">;
|
||||||
|
|
||||||
def FeatureMicroMips : SubtargetFeature<"micromips", "InMicroMipsMode", "true",
|
def FeatureMicroMips : SubtargetFeature<"micromips", "InMicroMipsMode", "true",
|
||||||
"microMips mode">;
|
"microMips mode">;
|
||||||
|
|
||||||
|
@ -1420,6 +1420,10 @@ include "Mips16InstrInfo.td"
|
|||||||
include "MipsDSPInstrFormats.td"
|
include "MipsDSPInstrFormats.td"
|
||||||
include "MipsDSPInstrInfo.td"
|
include "MipsDSPInstrInfo.td"
|
||||||
|
|
||||||
|
// MSA
|
||||||
|
include "MipsMSAInstrFormats.td"
|
||||||
|
include "MipsMSAInstrInfo.td"
|
||||||
|
|
||||||
// Micromips
|
// Micromips
|
||||||
include "MicroMipsInstrFormats.td"
|
include "MicroMipsInstrFormats.td"
|
||||||
include "MicroMipsInstrInfo.td"
|
include "MicroMipsInstrInfo.td"
|
||||||
|
34
lib/Target/Mips/MipsMSAInstrFormats.td
Normal file
34
lib/Target/Mips/MipsMSAInstrFormats.td
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//===- MipsMSAInstrFormats.td - Mips Instruction Formats ---*- tablegen -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def HasMSA : Predicate<"Subtarget.hasMSA()">,
|
||||||
|
AssemblerPredicate<"FeatureMSA">;
|
||||||
|
|
||||||
|
class MSAInst : MipsInst<(outs), (ins), "", [], NoItinerary, FrmOther> {
|
||||||
|
let Predicates = [HasMSA];
|
||||||
|
let Inst{31-26} = 0b011110;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PseudoMSA<dag outs, dag ins, list<dag> pattern,
|
||||||
|
InstrItinClass itin = IIPseudo>:
|
||||||
|
MipsPseudo<outs, ins, pattern, itin> {
|
||||||
|
let Predicates = [HasMSA];
|
||||||
|
}
|
||||||
|
|
||||||
|
class MSA_3R_FMT<bits<3> major, bits<2> df, bits<6> minor>: MSAInst {
|
||||||
|
let Inst{25-23} = major;
|
||||||
|
let Inst{22-21} = df;
|
||||||
|
let Inst{5-0} = minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MSA_I5_FMT<bits<3> major, bits<2> df, bits<6> minor>: MSAInst {
|
||||||
|
let Inst{25-23} = major;
|
||||||
|
let Inst{22-21} = df;
|
||||||
|
let Inst{5-0} = minor;
|
||||||
|
}
|
69
lib/Target/Mips/MipsMSAInstrInfo.td
Normal file
69
lib/Target/Mips/MipsMSAInstrInfo.td
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
//===- MipsMSAInstrInfo.td - MSA ASE instructions -*- 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 Mips MSA ASE instructions.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Instruction encoding.
|
||||||
|
class LD_B_ENC : MSA_I5_FMT<0b110, 0b00, 0b000111>;
|
||||||
|
class LD_H_ENC : MSA_I5_FMT<0b110, 0b01, 0b000111>;
|
||||||
|
class LD_W_ENC : MSA_I5_FMT<0b110, 0b10, 0b000111>;
|
||||||
|
class LD_D_ENC : MSA_I5_FMT<0b110, 0b11, 0b000111>;
|
||||||
|
class ST_B_ENC : MSA_I5_FMT<0b111, 0b00, 0b000111>;
|
||||||
|
class ST_H_ENC : MSA_I5_FMT<0b111, 0b01, 0b000111>;
|
||||||
|
class ST_W_ENC : MSA_I5_FMT<0b111, 0b10, 0b000111>;
|
||||||
|
class ST_D_ENC : MSA_I5_FMT<0b111, 0b11, 0b000111>;
|
||||||
|
|
||||||
|
// Instruction desc.
|
||||||
|
class LD_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
|
||||||
|
ValueType TyNode, InstrItinClass itin, RegisterClass RCWD,
|
||||||
|
Operand MemOpnd = mem, ComplexPattern Addr = addr> {
|
||||||
|
dag OutOperandList = (outs RCWD:$wd);
|
||||||
|
dag InOperandList = (ins MemOpnd:$addr);
|
||||||
|
string AsmString = !strconcat(instr_asm, "\t$wd, $addr");
|
||||||
|
list<dag> Pattern = [(set RCWD:$wd, (TyNode (OpNode Addr:$addr)))];
|
||||||
|
InstrItinClass Itinerary = itin;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ST_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
|
||||||
|
ValueType TyNode, InstrItinClass itin, RegisterClass RCWD,
|
||||||
|
Operand MemOpnd = mem, ComplexPattern Addr = addr> {
|
||||||
|
dag OutOperandList = (outs);
|
||||||
|
dag InOperandList = (ins RCWD:$wd, MemOpnd:$addr);
|
||||||
|
string AsmString = !strconcat(instr_asm, "\t$wd, $addr");
|
||||||
|
list<dag> Pattern = [(OpNode (TyNode RCWD:$wd), Addr:$addr)];
|
||||||
|
InstrItinClass Itinerary = itin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load/Store
|
||||||
|
class LD_B_DESC : LD_DESC_BASE<"ld.b", load, v16i8, NoItinerary, MSA128>;
|
||||||
|
class LD_H_DESC : LD_DESC_BASE<"ld.h", load, v8i16, NoItinerary, MSA128>;
|
||||||
|
class LD_W_DESC : LD_DESC_BASE<"ld.w", load, v4i32, NoItinerary, MSA128>;
|
||||||
|
class LD_D_DESC : LD_DESC_BASE<"ld.d", load, v2i64, NoItinerary, MSA128>;
|
||||||
|
class ST_B_DESC : ST_DESC_BASE<"st.b", store, v16i8, NoItinerary, MSA128>;
|
||||||
|
class ST_H_DESC : ST_DESC_BASE<"st.h", store, v8i16, NoItinerary, MSA128>;
|
||||||
|
class ST_W_DESC : ST_DESC_BASE<"st.w", store, v4i32, NoItinerary, MSA128>;
|
||||||
|
class ST_D_DESC : ST_DESC_BASE<"st.d", store, v2i64, NoItinerary, MSA128>;
|
||||||
|
|
||||||
|
// Instruction defs.
|
||||||
|
def LD_B: LD_B_ENC, LD_B_DESC, Requires<[HasMSA]>;
|
||||||
|
def LD_H: LD_H_ENC, LD_H_DESC, Requires<[HasMSA]>;
|
||||||
|
def LD_W: LD_W_ENC, LD_W_DESC, Requires<[HasMSA]>;
|
||||||
|
def LD_D: LD_D_ENC, LD_D_DESC, Requires<[HasMSA]>;
|
||||||
|
|
||||||
|
def ST_B: ST_B_ENC, ST_B_DESC, Requires<[HasMSA]>;
|
||||||
|
def ST_H: ST_H_ENC, ST_H_DESC, Requires<[HasMSA]>;
|
||||||
|
def ST_W: ST_W_ENC, ST_W_DESC, Requires<[HasMSA]>;
|
||||||
|
def ST_D: ST_D_ENC, ST_D_DESC, Requires<[HasMSA]>;
|
||||||
|
|
||||||
|
// Patterns.
|
||||||
|
class MSAPat<dag pattern, dag result, Predicate pred = HasMSA> :
|
||||||
|
Pat<pattern, result>, Requires<[pred]>;
|
||||||
|
|
@ -14,6 +14,7 @@ let Namespace = "Mips" in {
|
|||||||
def sub_fpeven : SubRegIndex<32>;
|
def sub_fpeven : SubRegIndex<32>;
|
||||||
def sub_fpodd : SubRegIndex<32, 32>;
|
def sub_fpodd : SubRegIndex<32, 32>;
|
||||||
def sub_32 : SubRegIndex<32>;
|
def sub_32 : SubRegIndex<32>;
|
||||||
|
def sub_64 : SubRegIndex<64>;
|
||||||
def sub_lo : SubRegIndex<32>;
|
def sub_lo : SubRegIndex<32>;
|
||||||
def sub_hi : SubRegIndex<32, 32>;
|
def sub_hi : SubRegIndex<32, 32>;
|
||||||
def sub_dsp16_19 : SubRegIndex<4, 16>;
|
def sub_dsp16_19 : SubRegIndex<4, 16>;
|
||||||
@ -63,6 +64,12 @@ class AFPR64<bits<16> Enc, string n, list<Register> subregs>
|
|||||||
let SubRegIndices = [sub_32];
|
let SubRegIndices = [sub_32];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mips 128-bit (aliased) MSA Registers
|
||||||
|
class AFPR128<bits<16> Enc, string n, list<Register> subregs>
|
||||||
|
: MipsRegWithSubRegs<Enc, n, subregs> {
|
||||||
|
let SubRegIndices = [sub_64];
|
||||||
|
}
|
||||||
|
|
||||||
// Accumulator Registers
|
// Accumulator Registers
|
||||||
class ACCReg<bits<16> Enc, string n, list<Register> subregs>
|
class ACCReg<bits<16> Enc, string n, list<Register> subregs>
|
||||||
: MipsRegWithSubRegs<Enc, n, subregs> {
|
: MipsRegWithSubRegs<Enc, n, subregs> {
|
||||||
@ -162,6 +169,41 @@ let Namespace = "Mips" in {
|
|||||||
def D#I#_64 : AFPR64<I, "f"#I, [!cast<FPR>("F"#I)]>,
|
def D#I#_64 : AFPR64<I, "f"#I, [!cast<FPR>("F"#I)]>,
|
||||||
DwarfRegNum<[!add(I, 32)]>;
|
DwarfRegNum<[!add(I, 32)]>;
|
||||||
|
|
||||||
|
/// Mips MSA registers
|
||||||
|
/// MSA and FPU cannot both be present unless the FPU has 64-bit registers
|
||||||
|
def W0 : AFPR128<0, "w0", [D0_64]>, DwarfRegNum<[32]>;
|
||||||
|
def W1 : AFPR128<1, "w1", [D1_64]>, DwarfRegNum<[33]>;
|
||||||
|
def W2 : AFPR128<2, "w2", [D2_64]>, DwarfRegNum<[34]>;
|
||||||
|
def W3 : AFPR128<3, "w3", [D3_64]>, DwarfRegNum<[35]>;
|
||||||
|
def W4 : AFPR128<4, "w4", [D4_64]>, DwarfRegNum<[36]>;
|
||||||
|
def W5 : AFPR128<5, "w5", [D5_64]>, DwarfRegNum<[37]>;
|
||||||
|
def W6 : AFPR128<6, "w6", [D6_64]>, DwarfRegNum<[38]>;
|
||||||
|
def W7 : AFPR128<7, "w7", [D7_64]>, DwarfRegNum<[39]>;
|
||||||
|
def W8 : AFPR128<8, "w8", [D8_64]>, DwarfRegNum<[40]>;
|
||||||
|
def W9 : AFPR128<9, "w9", [D9_64]>, DwarfRegNum<[41]>;
|
||||||
|
def W10 : AFPR128<10, "w10", [D10_64]>, DwarfRegNum<[42]>;
|
||||||
|
def W11 : AFPR128<11, "w11", [D11_64]>, DwarfRegNum<[43]>;
|
||||||
|
def W12 : AFPR128<12, "w12", [D12_64]>, DwarfRegNum<[44]>;
|
||||||
|
def W13 : AFPR128<13, "w13", [D13_64]>, DwarfRegNum<[45]>;
|
||||||
|
def W14 : AFPR128<14, "w14", [D14_64]>, DwarfRegNum<[46]>;
|
||||||
|
def W15 : AFPR128<15, "w15", [D15_64]>, DwarfRegNum<[47]>;
|
||||||
|
def W16 : AFPR128<16, "w16", [D16_64]>, DwarfRegNum<[48]>;
|
||||||
|
def W17 : AFPR128<17, "w17", [D17_64]>, DwarfRegNum<[49]>;
|
||||||
|
def W18 : AFPR128<18, "w18", [D18_64]>, DwarfRegNum<[50]>;
|
||||||
|
def W19 : AFPR128<19, "w19", [D19_64]>, DwarfRegNum<[51]>;
|
||||||
|
def W20 : AFPR128<20, "w20", [D20_64]>, DwarfRegNum<[52]>;
|
||||||
|
def W21 : AFPR128<21, "w21", [D21_64]>, DwarfRegNum<[53]>;
|
||||||
|
def W22 : AFPR128<22, "w22", [D22_64]>, DwarfRegNum<[54]>;
|
||||||
|
def W23 : AFPR128<23, "w23", [D23_64]>, DwarfRegNum<[55]>;
|
||||||
|
def W24 : AFPR128<24, "w24", [D24_64]>, DwarfRegNum<[56]>;
|
||||||
|
def W25 : AFPR128<25, "w25", [D25_64]>, DwarfRegNum<[57]>;
|
||||||
|
def W26 : AFPR128<26, "w26", [D26_64]>, DwarfRegNum<[58]>;
|
||||||
|
def W27 : AFPR128<27, "w27", [D27_64]>, DwarfRegNum<[59]>;
|
||||||
|
def W28 : AFPR128<28, "w28", [D28_64]>, DwarfRegNum<[60]>;
|
||||||
|
def W29 : AFPR128<29, "w29", [D29_64]>, DwarfRegNum<[61]>;
|
||||||
|
def W30 : AFPR128<30, "w30", [D30_64]>, DwarfRegNum<[62]>;
|
||||||
|
def W31 : AFPR128<31, "w31", [D31_64]>, DwarfRegNum<[63]>;
|
||||||
|
|
||||||
// Hi/Lo registers
|
// Hi/Lo registers
|
||||||
def HI : Register<"ac0">, DwarfRegNum<[64]>;
|
def HI : Register<"ac0">, DwarfRegNum<[64]>;
|
||||||
def HI1 : Register<"ac1">, DwarfRegNum<[176]>;
|
def HI1 : Register<"ac1">, DwarfRegNum<[176]>;
|
||||||
@ -302,6 +344,9 @@ def CCR : RegisterClass<"Mips", [i32], 32, (sequence "FCR%u", 0, 31)>,
|
|||||||
def FCC : RegisterClass<"Mips", [i32], 32, (sequence "FCC%u", 0, 7)>,
|
def FCC : RegisterClass<"Mips", [i32], 32, (sequence "FCC%u", 0, 7)>,
|
||||||
Unallocatable;
|
Unallocatable;
|
||||||
|
|
||||||
|
def MSA128: RegisterClass<"Mips", [v16i8, v8i16, v4i32, v2i64], 128,
|
||||||
|
(sequence "W%u", 0, 31)>;
|
||||||
|
|
||||||
// Hi/Lo Registers
|
// Hi/Lo Registers
|
||||||
def LORegs : RegisterClass<"Mips", [i32], 32, (add LO)>;
|
def LORegs : RegisterClass<"Mips", [i32], 32, (add LO)>;
|
||||||
def HIRegs : RegisterClass<"Mips", [i32], 32, (add HI)>;
|
def HIRegs : RegisterClass<"Mips", [i32], 32, (add HI)>;
|
||||||
|
@ -77,6 +77,23 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
|
|||||||
if (Subtarget->hasDSPR2())
|
if (Subtarget->hasDSPR2())
|
||||||
setOperationAction(ISD::MUL, MVT::v2i16, Legal);
|
setOperationAction(ISD::MUL, MVT::v2i16, Legal);
|
||||||
|
|
||||||
|
if (Subtarget->hasMSA()) {
|
||||||
|
MVT::SimpleValueType VecTys[4] = {MVT::v16i8, MVT::v8i16,
|
||||||
|
MVT::v4i32, MVT::v2i64};
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
|
||||||
|
addRegisterClass(VecTys[i], &Mips::MSA128RegClass);
|
||||||
|
|
||||||
|
// Expand all builtin opcodes.
|
||||||
|
for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
|
||||||
|
setOperationAction(Opc, VecTys[i], Expand);
|
||||||
|
|
||||||
|
setOperationAction(ISD::LOAD, VecTys[i], Legal);
|
||||||
|
setOperationAction(ISD::STORE, VecTys[i], Legal);
|
||||||
|
setOperationAction(ISD::BITCAST, VecTys[i], Legal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!TM.Options.UseSoftFloat) {
|
if (!TM.Options.UseSoftFloat) {
|
||||||
addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
|
addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,
|
|||||||
HasBitCount(false), HasFPIdx(false),
|
HasBitCount(false), HasFPIdx(false),
|
||||||
InMips16Mode(false), InMips16HardFloat(Mips16HardFloat),
|
InMips16Mode(false), InMips16HardFloat(Mips16HardFloat),
|
||||||
InMicroMipsMode(false), HasDSP(false), HasDSPR2(false),
|
InMicroMipsMode(false), HasDSP(false), HasDSPR2(false),
|
||||||
AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16),
|
AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), HasMSA(false),
|
||||||
RM(_RM), OverrideMode(NoOverride), TM(_TM)
|
RM(_RM), OverrideMode(NoOverride), TM(_TM)
|
||||||
{
|
{
|
||||||
std::string CPUName = CPU;
|
std::string CPUName = CPU;
|
||||||
|
@ -113,6 +113,9 @@ protected:
|
|||||||
// compiled as Mips32
|
// compiled as Mips32
|
||||||
bool Os16;
|
bool Os16;
|
||||||
|
|
||||||
|
// HasMSA -- supports MSA ASE.
|
||||||
|
bool HasMSA;
|
||||||
|
|
||||||
InstrItineraryData InstrItins;
|
InstrItineraryData InstrItins;
|
||||||
|
|
||||||
// The instance to the register info section object
|
// The instance to the register info section object
|
||||||
@ -182,6 +185,7 @@ public:
|
|||||||
bool inMicroMipsMode() const { return InMicroMipsMode; }
|
bool inMicroMipsMode() const { return InMicroMipsMode; }
|
||||||
bool hasDSP() const { return HasDSP; }
|
bool hasDSP() const { return HasDSP; }
|
||||||
bool hasDSPR2() const { return HasDSPR2; }
|
bool hasDSPR2() const { return HasDSPR2; }
|
||||||
|
bool hasMSA() const { return HasMSA; }
|
||||||
bool isLinux() const { return IsLinux; }
|
bool isLinux() const { return IsLinux; }
|
||||||
bool useSmallSection() const { return UseSmallSection; }
|
bool useSmallSection() const { return UseSmallSection; }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user