Skip to content

Commit

Permalink
[mips] Include EVA instructions in Std2MicroMips mapping tables
Browse files Browse the repository at this point in the history
This patch includes EVA instructions in the Std2MicroMips mapping
tables, which is required for direct object emission.

Differential Revision: https://reviews.llvm.org/D41771

llvm-svn: 323958
  • Loading branch information
Aleksandar Beserminji authored and Aleksandar Beserminji committed Feb 1, 2018
1 parent cda2526 commit a330c20
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 23 deletions.
2 changes: 1 addition & 1 deletion llvm/lib/Target/Mips/MicroMipsInstrFormats.td
Expand Up @@ -699,7 +699,7 @@ class LL_FM_MM<bits<4> funct> : MMArch {
let Inst{11-0} = addr{11-0};
}

class LLE_FM_MM<bits<4> funct> {
class LLE_FM_MM<bits<4> funct> : MMArch {
bits<5> rt;
bits<21> addr;
bits<5> base = addr{20-16};
Expand Down
28 changes: 18 additions & 10 deletions llvm/lib/Target/Mips/MicroMipsInstrInfo.td
Expand Up @@ -273,6 +273,7 @@ class LLEBaseMM<string opstr, RegisterOperand RO> :
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;
}

Expand All @@ -288,6 +289,7 @@ class SCEBaseMM<string opstr, RegisterOperand RO> :
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";
}
Expand Down Expand Up @@ -777,21 +779,27 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
}

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>;
}

Expand Down Expand Up @@ -971,8 +979,8 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
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>,
Expand Down
29 changes: 17 additions & 12 deletions llvm/lib/Target/Mips/MipsEVAInstrInfo.td
Expand Up @@ -59,6 +59,7 @@ class LOAD_EVA_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
list<dag> Pattern = [];
string DecoderMethod = "DecodeMemEVA";
bit canFoldAsLoad = 1;
string BaseOpcode = instr_asm;
bit mayLoad = 1;
InstrItinClass Itinerary = itin;
}
Expand All @@ -77,6 +78,7 @@ class STORE_EVA_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
string AsmString = !strconcat(instr_asm, "\t$rt, $addr");
list<dag> Pattern = [];
string DecoderMethod = "DecodeMemEVA";
string BaseOpcode = instr_asm;
bit mayStore = 1;
InstrItinClass Itinerary = itin;
}
Expand Down Expand Up @@ -121,6 +123,7 @@ class LLE_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
dag InOperandList = (ins mem_simm9:$addr);
string AsmString = !strconcat(instr_asm, "\t$rt, $addr");
list<dag> Pattern = [];
string BaseOpcode = instr_asm;
bit mayLoad = 1;
string DecoderMethod = "DecodeMemEVA";
InstrItinClass Itinerary = itin;
Expand All @@ -134,6 +137,7 @@ class SCE_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
dag InOperandList = (ins GPROpnd:$rt, mem_simm9:$addr);
string AsmString = !strconcat(instr_asm, "\t$rt, $addr");
list<dag> Pattern = [];
string BaseOpcode = instr_asm;
bit mayStore = 1;
string Constraints = "$rt = $dst";
string DecoderMethod = "DecodeMemEVA";
Expand All @@ -159,6 +163,7 @@ class CACHEE_DESC_BASE<string instr_asm, Operand MemOpnd,
dag InOperandList = (ins MemOpnd:$addr, uimm5:$hint);
string AsmString = !strconcat(instr_asm, "\t$hint, $addr");
list<dag> Pattern = [];
string BaseOpcode = instr_asm;
string DecoderMethod = "DecodeCacheeOp_CacheOpR6";
InstrItinClass Itinerary = itin;
}
Expand All @@ -173,17 +178,17 @@ class PREFE_DESC : CACHEE_DESC_BASE<"prefe", mem_simm9, II_PREFE>;
//===----------------------------------------------------------------------===//

/// 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
Expand All @@ -196,14 +201,14 @@ def SWRE : SWRE_ENC, SWRE_DESC, INSN_EVA_NOT_32R6_64R6;

/// 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 {
def TLBINV : TLBINV_ENC, TLBINV_DESC, INSN_EVA;
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;
2 changes: 2 additions & 0 deletions llvm/lib/Target/Mips/MipsInstrInfo.td
Expand Up @@ -1333,6 +1333,7 @@ class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
[(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
let DecoderMethod = "DecodeMem";
let canFoldAsLoad = 1;
string BaseOpcode = opstr;
let mayLoad = 1;
}

Expand All @@ -1346,6 +1347,7 @@ class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
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;
}

Expand Down
213 changes: 213 additions & 0 deletions llvm/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)

0 comments on commit a330c20

Please sign in to comment.