diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index c12a32e3d80..b1c3fb808d3 100644 --- a/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -302,3 +302,16 @@ class TEQI_FM_MM funct> : MMArch { let Inst{20-16} = rs; let Inst{15-0} = imm16; } + +class LL_FM_MM funct> { + bits<5> rt; + bits<21> addr; + + bits<32> Inst; + + let Inst{31-26} = 0x18; + let Inst{25-21} = rt; + let Inst{20-16} = addr{20-16}; + let Inst{15-12} = funct; + let Inst{11-0} = addr{11-0}; +} diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 846ced0883d..76463892fae 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -45,6 +45,21 @@ class StoreLeftRightMM : + InstSE<(outs RO:$rt), (ins mem_mm_12:$addr), + !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> { + let DecoderMethod = "DecodeMem"; + let mayLoad = 1; +} + +class SCBaseMM : + InstSE<(outs RO:$dst), (ins RO:$rt, mem_mm_12:$addr), + !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> { + let DecoderMethod = "DecodeMem"; + let mayStore = 1; + let Constraints = "$rt = $dst"; +} + let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { /// Arithmetic Instructions (ALU Immediate) def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd>, @@ -212,4 +227,8 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def TLTI_MM : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM_MM<0x08>; def TLTIU_MM : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM_MM<0x0a>; def TNEI_MM : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM_MM<0x0c>; + + /// Load-linked, Store-conditional + def LL_MM : LLBaseMM<"ll", GPR32Opnd>, LL_FM_MM<0x3>; + def SC_MM : SCBaseMM<"sc", GPR32Opnd>, LL_FM_MM<0xb>; } diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 8f3c2649079..9c74ae4ce2b 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -392,6 +392,8 @@ MipsTargetLowering(MipsTargetMachine &TM) setExceptionSelectorRegister(IsN64 ? Mips::A1_64 : Mips::A1); MaxStoresPerMemcpy = 16; + + isMicroMips = Subtarget->inMicroMipsMode(); } const MipsTargetLowering *MipsTargetLowering::create(MipsTargetMachine &TM) { @@ -931,8 +933,8 @@ MipsTargetLowering::emitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, unsigned LL, SC, AND, NOR, ZERO, BEQ; if (Size == 4) { - LL = Mips::LL; - SC = Mips::SC; + LL = isMicroMips ? Mips::LL_MM : Mips::LL; + SC = isMicroMips ? Mips::SC_MM : Mips::SC; AND = Mips::AND; NOR = Mips::NOR; ZERO = Mips::ZERO; @@ -1174,8 +1176,8 @@ MachineBasicBlock * MipsTargetLowering::emitAtomicCmpSwap(MachineInstr *MI, unsigned LL, SC, ZERO, BNE, BEQ; if (Size == 4) { - LL = Mips::LL; - SC = Mips::SC; + LL = isMicroMips ? Mips::LL_MM : Mips::LL; + SC = isMicroMips ? Mips::SC_MM : Mips::SC; ZERO = Mips::ZERO; BNE = Mips::BNE; BEQ = Mips::BEQ; diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 65f68f04315..2214fd18fe2 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -209,6 +209,7 @@ namespace llvm { class MipsFunctionInfo; class MipsTargetLowering : public TargetLowering { + bool isMicroMips; public: explicit MipsTargetLowering(MipsTargetMachine &TM); diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 307e0fb8cc1..12bddf06993 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -1012,8 +1012,10 @@ def DI : DEI_FT<"di", GPR32Opnd>, EI_FM<0>; def WAIT : WAIT_FT<"wait">; /// Load-linked, Store-conditional +let Predicates = [NotInMicroMips] in { def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>; def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>; +} /// Jump and Branch Instructions def J : MMRel, JumpFJ, FJ<2>, diff --git a/test/MC/Mips/micromips-loadstore-instructions.s b/test/MC/Mips/micromips-loadstore-instructions.s index cc7514b3231..4885e4e34d8 100644 --- a/test/MC/Mips/micromips-loadstore-instructions.s +++ b/test/MC/Mips/micromips-loadstore-instructions.s @@ -1,5 +1,7 @@ -# RUN: llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips | FileCheck -check-prefix=CHECK-EL %s -# RUN: llvm-mc %s -triple=mips -show-encoding -mattr=micromips | FileCheck -check-prefix=CHECK-EB %s +# RUN: llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips \ +# RUN: | FileCheck -check-prefix=CHECK-EL %s +# RUN: llvm-mc %s -triple=mips -show-encoding -mattr=micromips \ +# RUN: | FileCheck -check-prefix=CHECK-EB %s # Check that the assembler can handle the documented syntax # for load and store instructions. #------------------------------------------------------------------------------ @@ -15,6 +17,8 @@ # CHECK-EL: sb $5, 8($4) # encoding: [0xa4,0x18,0x08,0x00] # CHECK-EL: sh $2, 8($4) # encoding: [0x44,0x38,0x08,0x00] # CHECK-EL: sw $5, 4($6) # encoding: [0xa6,0xf8,0x04,0x00] +# CHECK-EL: ll $2, 8($4) # encoding: [0x44,0x60,0x08,0x30] +# CHECK-EL: sc $2, 8($4) # encoding: [0x44,0x60,0x08,0xb0] #------------------------------------------------------------------------------ # Big endian #------------------------------------------------------------------------------ @@ -26,6 +30,8 @@ # CHECK-EB: sb $5, 8($4) # encoding: [0x18,0xa4,0x00,0x08] # CHECK-EB: sh $2, 8($4) # encoding: [0x38,0x44,0x00,0x08] # CHECK-EB: sw $5, 4($6) # encoding: [0xf8,0xa6,0x00,0x04] +# CHECK-EB: ll $2, 8($4) # encoding: [0x60,0x44,0x30,0x08] +# CHECK-EB: sc $2, 8($4) # encoding: [0x60,0x44,0xb0,0x08] lb $5, 8($4) lbu $6, 8($4) lh $2, 8($4) @@ -34,3 +40,5 @@ sb $5, 8($4) sh $2, 8($4) sw $5, 4($6) + ll $2, 8($4) + sc $2, 8($4)