Index: llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td +++ llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td @@ -699,7 +699,7 @@ let Inst{11-0} = addr{11-0}; } -class LLE_FM_MM funct> { +class LLE_FM_MM funct> : MMArch { bits<5> rt; bits<21> addr; bits<5> base = addr{20-16}; Index: llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td @@ -273,6 +273,7 @@ InstSE<(outs RO:$rt), (ins mem_simm9:$addr), !strconcat(opstr, "\t$rt, $addr"), [], II_LLE, FrmI> { let DecoderMethod = "DecodeMemMMImm9"; + string BaseOpcode = opstr; let mayLoad = 1; } @@ -288,6 +289,7 @@ InstSE<(outs RO:$dst), (ins RO:$rt, mem_simm9:$addr), !strconcat(opstr, "\t$rt, $addr"), [], II_SCE, FrmI> { let DecoderMethod = "DecodeMemMMImm9"; + string BaseOpcode = opstr; let mayStore = 1; let Constraints = "$rt = $dst"; } @@ -777,21 +779,27 @@ } let DecoderMethod = "DecodeMemMMImm9" in { - def LBE_MM : Load<"lbe", GPR32Opnd, null_frag, II_LBE>, + def LBE_MM : MMRel, Load<"lbe", GPR32Opnd, null_frag, II_LBE>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x4>; - def LBuE_MM : Load<"lbue", GPR32Opnd, null_frag, II_LBUE>, + def LBuE_MM : MMRel, Load<"lbue", GPR32Opnd, null_frag, II_LBUE>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x0>; - def LHE_MM : LoadMemory<"lhe", GPR32Opnd, mem_simm9, null_frag, II_LHE>, + def LHE_MM : MMRel, LoadMemory<"lhe", GPR32Opnd, mem_simm9, + null_frag, II_LHE>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x5>; - def LHuE_MM : LoadMemory<"lhue", GPR32Opnd, mem_simm9, null_frag, II_LHUE>, + def LHuE_MM : MMRel, LoadMemory<"lhue", GPR32Opnd, mem_simm9, + null_frag, II_LHUE>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x1>; - def LWE_MM : LoadMemory<"lwe", GPR32Opnd, mem_simm9, null_frag, II_LWE>, + def LWE_MM : MMRel, LoadMemory<"lwe", GPR32Opnd, mem_simm9, + null_frag, II_LWE>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x7>; - def SBE_MM : StoreMemory<"sbe", GPR32Opnd, mem_simm9, null_frag, II_SBE>, + def SBE_MM : MMRel, StoreMemory<"sbe", GPR32Opnd, mem_simm9, + null_frag, II_SBE>, POOL32C_LHUE_FM_MM<0x18, 0xa, 0x4>; - def SHE_MM : StoreMemory<"she", GPR32Opnd, mem_simm9, null_frag, II_SHE>, + def SHE_MM : MMRel, StoreMemory<"she", GPR32Opnd, mem_simm9, + null_frag, II_SHE>, POOL32C_LHUE_FM_MM<0x18, 0xa, 0x5>; - def SWE_MM : StoreMemory<"swe", GPR32Opnd, mem_simm9, null_frag, II_SWE>, + def SWE_MM : MMRel, StoreMemory<"swe", GPR32Opnd, mem_simm9, + null_frag, II_SWE>, POOL32C_LHUE_FM_MM<0x18, 0xa, 0x7>; } @@ -971,8 +979,8 @@ def LL_MM : LLBaseMM<"ll", GPR32Opnd>, LL_FM_MM<0x3>; def SC_MM : SCBaseMM<"sc", GPR32Opnd>, LL_FM_MM<0xb>; - def LLE_MM : LLEBaseMM<"lle", GPR32Opnd>, LLE_FM_MM<0x6>; - def SCE_MM : SCEBaseMM<"sce", GPR32Opnd>, LLE_FM_MM<0xA>; + def LLE_MM : MMRel, LLEBaseMM<"lle", GPR32Opnd>, LLE_FM_MM<0x6>; + def SCE_MM : MMRel, SCEBaseMM<"sce", GPR32Opnd>, LLE_FM_MM<0xA>; let DecoderMethod = "DecodeCacheOpMM" in { def CACHE_MM : MMRel, CacheOp<"cache", mem_mm_12, II_CACHE>, Index: llvm/trunk/lib/Target/Mips/MipsEVAInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MipsEVAInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MipsEVAInstrInfo.td @@ -59,6 +59,7 @@ list Pattern = []; string DecoderMethod = "DecodeMemEVA"; bit canFoldAsLoad = 1; + string BaseOpcode = instr_asm; bit mayLoad = 1; InstrItinClass Itinerary = itin; } @@ -77,6 +78,7 @@ string AsmString = !strconcat(instr_asm, "\t$rt, $addr"); list Pattern = []; string DecoderMethod = "DecodeMemEVA"; + string BaseOpcode = instr_asm; bit mayStore = 1; InstrItinClass Itinerary = itin; } @@ -121,6 +123,7 @@ dag InOperandList = (ins mem_simm9:$addr); string AsmString = !strconcat(instr_asm, "\t$rt, $addr"); list Pattern = []; + string BaseOpcode = instr_asm; bit mayLoad = 1; string DecoderMethod = "DecodeMemEVA"; InstrItinClass Itinerary = itin; @@ -134,6 +137,7 @@ dag InOperandList = (ins GPROpnd:$rt, mem_simm9:$addr); string AsmString = !strconcat(instr_asm, "\t$rt, $addr"); list Pattern = []; + string BaseOpcode = instr_asm; bit mayStore = 1; string Constraints = "$rt = $dst"; string DecoderMethod = "DecodeMemEVA"; @@ -159,6 +163,7 @@ dag InOperandList = (ins MemOpnd:$addr, uimm5:$hint); string AsmString = !strconcat(instr_asm, "\t$hint, $addr"); list Pattern = []; + string BaseOpcode = instr_asm; string DecoderMethod = "DecodeCacheeOp_CacheOpR6"; InstrItinClass Itinerary = itin; } @@ -173,17 +178,17 @@ //===----------------------------------------------------------------------===// /// Load and Store EVA Instructions -def LBE : LBE_ENC, LBE_DESC, INSN_EVA; -def LBuE : LBuE_ENC, LBuE_DESC, INSN_EVA; -def LHE : LHE_ENC, LHE_DESC, INSN_EVA; -def LHuE : LHuE_ENC, LHuE_DESC, INSN_EVA; +def LBE : MMRel, LBE_ENC, LBE_DESC, INSN_EVA; +def LBuE : MMRel, LBuE_ENC, LBuE_DESC, INSN_EVA; +def LHE : MMRel, LHE_ENC, LHE_DESC, INSN_EVA; +def LHuE : MMRel, LHuE_ENC, LHuE_DESC, INSN_EVA; let AdditionalPredicates = [NotInMicroMips] in { -def LWE : LWE_ENC, LWE_DESC, INSN_EVA; +def LWE : MMRel, LWE_ENC, LWE_DESC, INSN_EVA; } -def SBE : SBE_ENC, SBE_DESC, INSN_EVA; -def SHE : SHE_ENC, SHE_DESC, INSN_EVA; +def SBE : MMRel, SBE_ENC, SBE_DESC, INSN_EVA; +def SHE : MMRel, SHE_ENC, SHE_DESC, INSN_EVA; let AdditionalPredicates = [NotInMicroMips] in { -def SWE : SWE_ENC, SWE_DESC, INSN_EVA; +def SWE : MMRel, SWE_ENC, SWE_DESC, INSN_EVA; } /// load/store left/right EVA @@ -196,8 +201,8 @@ /// Load-linked EVA, Store-conditional EVA let AdditionalPredicates = [NotInMicroMips] in { -def LLE : LLE_ENC, LLE_DESC, INSN_EVA; -def SCE : SCE_ENC, SCE_DESC, INSN_EVA; +def LLE : MMRel, LLE_ENC, LLE_DESC, INSN_EVA; +def SCE : MMRel, SCE_ENC, SCE_DESC, INSN_EVA; } let AdditionalPredicates = [NotInMicroMips] in { @@ -205,5 +210,5 @@ def TLBINVF : TLBINVF_ENC, TLBINVF_DESC, INSN_EVA; } -def CACHEE : CACHEE_ENC, CACHEE_DESC, INSN_EVA; -def PREFE : PREFE_ENC, PREFE_DESC, INSN_EVA; +def CACHEE : MMRel, CACHEE_ENC, CACHEE_DESC, INSN_EVA; +def PREFE : MMRel, PREFE_ENC, PREFE_DESC, INSN_EVA; Index: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td @@ -1333,6 +1333,7 @@ [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMem"; let canFoldAsLoad = 1; + string BaseOpcode = opstr; let mayLoad = 1; } @@ -1346,6 +1347,7 @@ InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMem"; + string BaseOpcode = opstr; let mayStore = 1; } Index: llvm/trunk/test/CodeGen/Mips/micromips-eva.mir =================================================================== --- llvm/trunk/test/CodeGen/Mips/micromips-eva.mir +++ llvm/trunk/test/CodeGen/Mips/micromips-eva.mir @@ -0,0 +1,213 @@ +# RUN: llc -O0 -march=mips -mcpu=mips32r3 -mattr=+micromips -start-after=expand-isel-pseudos \ +# RUN: -filetype obj %s -o - | llvm-objdump -d - | FileCheck %s + +--- | + + @wArray = global [13 x i32] zeroinitializer, align 4 + @hArray = global [13 x i16] zeroinitializer, align 2 + @bArray = global [13 x i8] zeroinitializer, align 1 + + ; Function Attrs: noinline nounwind optnone + define void @_Z3foov() { + entry: + %0 = load i8, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @bArray, i32 0, i32 5), align 1 + %conv = sext i8 %0 to i32 + %sub = sub nsw i32 %conv, 7 + %conv1 = trunc i32 %sub to i8 + store i8 %conv1, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @bArray, i32 0, i32 3), align 1 + %1 = load i8, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @bArray, i32 0, i32 5), align 1 + %conv2 = sext i8 %1 to i32 + %sub3 = sub nsw i32 %conv2, 7 + %conv4 = trunc i32 %sub3 to i8 + store i8 %conv4, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @bArray, i32 0, i32 3), align 1 + %2 = load i16, i16* getelementptr inbounds ([13 x i16], [13 x i16]* @hArray, i32 0, i32 5), align 2 + %conv5 = sext i16 %2 to i32 + %sub6 = sub nsw i32 %conv5, 7 + %conv7 = trunc i32 %sub6 to i16 + store i16 %conv7, i16* getelementptr inbounds ([13 x i16], [13 x i16]* @hArray, i32 0, i32 3), align 2 + %3 = load i16, i16* getelementptr inbounds ([13 x i16], [13 x i16]* @hArray, i32 0, i32 5), align 2 + %conv8 = sext i16 %3 to i32 + %sub9 = sub nsw i32 %conv8, 7 + %conv10 = trunc i32 %sub9 to i16 + store i16 %conv10, i16* getelementptr inbounds ([13 x i16], [13 x i16]* @hArray, i32 0, i32 3), align 2 + %4 = load i32, i32* getelementptr inbounds ([13 x i32], [13 x i32]* @wArray, i32 0, i32 5), align 4 + %sub11 = sub nsw i32 %4, 7 + store i32 %sub11, i32* getelementptr inbounds ([13 x i32], [13 x i32]* @wArray, i32 0, i32 3), align 4 + ret void + } + + ; Function Attrs: noinline nounwind optnone + define i32 @_Z3barPi(i32* %z) { + entry: + %z.addr = alloca i32*, align 4 + store i32* %z, i32** %z.addr, align 4 + %0 = load i32*, i32** %z.addr, align 4 + fence seq_cst + %1 = atomicrmw add i32* %0, i32 42 monotonic + fence seq_cst + %2 = add i32 %1, 42 + ret i32 %2 + } + +... +--- +name: _Z3foov +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: gpr32, preferred-register: '' } + - { id: 1, class: gpr32, preferred-register: '' } + - { id: 2, class: gpr32, preferred-register: '' } + - { id: 3, class: gpr32, preferred-register: '' } + - { id: 4, class: gpr32, preferred-register: '' } + - { id: 5, class: gpr32, preferred-register: '' } + - { id: 6, class: gpr32, preferred-register: '' } + - { id: 7, class: gpr32, preferred-register: '' } + - { id: 8, class: gpr32, preferred-register: '' } + - { id: 9, class: gpr32, preferred-register: '' } + - { id: 10, class: gpr32, preferred-register: '' } + - { id: 11, class: gpr32, preferred-register: '' } + - { id: 12, class: gpr32, preferred-register: '' } + - { id: 13, class: gpr32, preferred-register: '' } + - { id: 14, class: gpr32, preferred-register: '' } + - { id: 15, class: gpr32, preferred-register: '' } +liveins: +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 1 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.entry: + %0:gpr32 = LUi target-flags(mips-abs-hi) @bArray + %1:gpr32 = ADDiu killed %0, target-flags(mips-abs-lo) @bArray + %2:gpr32 = LBuE %1, 5 :: (dereferenceable load 1 from `i8* getelementptr inbounds ([13 x i8], [13 x i8]* @bArray, i32 0, i32 5)`) + %3:gpr32 = ADDiu killed %2, -7 + SBE killed %3, %1, 3 :: (store 1 into `i8* getelementptr inbounds ([13 x i8], [13 x i8]* @bArray, i32 0, i32 3)`) + %4:gpr32 = LBE %1, 5 :: (dereferenceable load 1 from `i8* getelementptr inbounds ([13 x i8], [13 x i8]* @bArray, i32 0, i32 5)`) + %5:gpr32 = ADDiu killed %4, -7 + SBE killed %5, %1, 3 :: (store 1 into `i8* getelementptr inbounds ([13 x i8], [13 x i8]* @bArray, i32 0, i32 3)`) + %6:gpr32 = LUi target-flags(mips-abs-hi) @hArray + %7:gpr32 = ADDiu killed %6, target-flags(mips-abs-lo) @hArray + %8:gpr32 = LHuE %7, 10 :: (dereferenceable load 2 from `i16* getelementptr inbounds ([13 x i16], [13 x i16]* @hArray, i32 0, i32 5)`) + %9:gpr32 = ADDiu killed %8, -7 + SHE killed %9, %7, 6 :: (store 2 into `i16* getelementptr inbounds ([13 x i16], [13 x i16]* @hArray, i32 0, i32 3)`) + %10:gpr32 = LHE %7, 10 :: (dereferenceable load 2 from `i16* getelementptr inbounds ([13 x i16], [13 x i16]* @hArray, i32 0, i32 5)`) + %11:gpr32 = ADDiu killed %10, -7 + SHE killed %11, %7, 6 :: (store 2 into `i16* getelementptr inbounds ([13 x i16], [13 x i16]* @hArray, i32 0, i32 3)`) + %12:gpr32 = LUi target-flags(mips-abs-hi) @wArray + %13:gpr32 = ADDiu killed %12, target-flags(mips-abs-lo) @wArray + %14:gpr32 = LWE %13, 20 :: (dereferenceable load 4 from `i32* getelementptr inbounds ([13 x i32], [13 x i32]* @wArray, i32 0, i32 5)`) + %15:gpr32 = ADDiu killed %14, -7 + SWE killed %15, %13, 12 :: (store 4 into `i32* getelementptr inbounds ([13 x i32], [13 x i32]* @wArray, i32 0, i32 3)`) + RetRA + +... +--- +name: _Z3barPi +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: gpr32, preferred-register: '' } + - { id: 1, class: gpr32, preferred-register: '' } + - { id: 2, class: gpr32, preferred-register: '' } + - { id: 3, class: gpr32, preferred-register: '' } + - { id: 4, class: gpr32, preferred-register: '' } + - { id: 5, class: gpr32, preferred-register: '' } + - { id: 6, class: gpr32, preferred-register: '' } + - { id: 7, class: gpr32, preferred-register: '' } + - { id: 8, class: gpr32, preferred-register: '' } +liveins: + - { reg: '$a0', virtual-reg: '%0' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 4 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + savePoint: '' + restorePoint: '' +fixedStack: +stack: + - { id: 0, name: z.addr, type: default, offset: 0, size: 4, alignment: 4, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + di-variable: '', di-expression: '', di-location: '' } +constants: +body: | + bb.0.entry: + successors: %bb.1(0x80000000) + liveins: $a0 + + %0:gpr32 = COPY $a0 + %1:gpr32 = COPY %0 + SW %0, %stack.0.z.addr, 0 :: (store 4 into %ir.z.addr) + %2:gpr32 = LW %stack.0.z.addr, 0 :: (dereferenceable load 4 from %ir.z.addr) + SYNC 0 + %3:gpr32 = ADDiu $zero, 42 + + bb.1.entry: + successors: %bb.1(0x40000000), %bb.2(0x40000000) + + %4:gpr32 = LLE %2, 0 + %6:gpr32 = ADDu %4, %3 + %8:gpr32 = SCE %6, %2, 0 + BEQ %8, $zero, %bb.1, implicit-def $at + + bb.2.entry: + SYNC 0 + %5:gpr32 = ADDiu killed %4, 42 + $v0 = COPY %5 + CACHEE %1, 5, 2 + PREFE %1, 5, 2 + RetRA implicit $v0 + +... + +# CHECK: 60 41 60 05 lbue $2, 5($1) +# CHECK: 60 41 68 05 lbe $2, 5($1) +# CHECK: 60 41 a8 03 sbe $2, 3($1) + +# CHECK: 60 41 62 0a lhue $2, 10($1) +# CHECK: 60 41 6a 0a lhe $2, 10($1) +# CHECK: 60 41 aa 06 she $2, 6($1) + +# CHECK: 60 41 6e 14 lwe $2, 20($1) +# CHECK: 60 41 ae 0c swe $2, 12($1) + +# CHECK: 60 41 6c 00 lle $2, 0($1) +# CHECK: 60 81 ac 00 sce $4, 0($1) + +# CHECK: 60 41 a6 05 cachee 2, 5($1) +# CHECK: 60 41 a4 05 prefe 2, 5($1)