forked from OSchip/llvm-project
[mips] Add microMIPS specific addressing patterns.
These are identical but use microMIPS instructions instead of MIPS instructions. Also, flatten the 'let AdditionalPredicates = [InMicroMips]' by using the ISA_MICROMIPS adjective. Add tests for constant materialization. Reviewers: atanasyan, abeserminji, smaksimovic Differential Revision: https://reviews.llvm.org/D48275 llvm-svn: 335185
This commit is contained in:
parent
d1d83df807
commit
0f111dd704
|
@ -1165,75 +1165,96 @@ let DecoderNamespace = "MicroMips" in {
|
|||
// MicroMips arbitrary patterns that map to one or more instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let AdditionalPredicates = [InMicroMips] in {
|
||||
def : MipsPat<(i32 immLi16:$imm),
|
||||
(LI16_MM immLi16:$imm)>;
|
||||
defm : MipsHiLoRelocs<LUi_MM, ADDiu_MM, ZERO, GPR32Opnd>, ISA_MICROMIPS;
|
||||
|
||||
defm : MaterializeImms<i32, ZERO, ADDiu_MM, LUi_MM, ORi_MM>;
|
||||
}
|
||||
def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi_MM tglobaladdr:$in)>,
|
||||
ISA_MICROMIPS;
|
||||
def : MipsPat<(MipsGotHi texternalsym:$in), (LUi_MM texternalsym:$in)>,
|
||||
ISA_MICROMIPS;
|
||||
|
||||
let Predicates = [InMicroMips] in {
|
||||
def : MipsPat<(not GPRMM16:$in),
|
||||
(NOT16_MM GPRMM16:$in)>;
|
||||
def : MipsPat<(not GPR32:$in),
|
||||
(NOR_MM GPR32Opnd:$in, ZERO)>;
|
||||
// gp_rel relocs
|
||||
def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
|
||||
(ADDiu_MM GPR32:$gp, tglobaladdr:$in)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
|
||||
(ADDiu_MM GPR32:$gp, tconstpool:$in)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(add GPRMM16:$src, immSExtAddiur2:$imm),
|
||||
(ADDIUR2_MM GPRMM16:$src, immSExtAddiur2:$imm)>;
|
||||
def : MipsPat<(add GPR32:$src, immSExtAddius5:$imm),
|
||||
(ADDIUS5_MM GPR32:$src, immSExtAddius5:$imm)>;
|
||||
def : MipsPat<(add GPR32:$src, immSExt16:$imm),
|
||||
(ADDiu_MM GPR32:$src, immSExt16:$imm)>;
|
||||
def : WrapperPat<tglobaladdr, ADDiu_MM, GPR32>, ISA_MICROMIPS;
|
||||
def : WrapperPat<tconstpool, ADDiu_MM, GPR32>, ISA_MICROMIPS;
|
||||
def : WrapperPat<texternalsym, ADDiu_MM, GPR32>, ISA_MICROMIPS;
|
||||
def : WrapperPat<tblockaddress, ADDiu_MM, GPR32>, ISA_MICROMIPS;
|
||||
def : WrapperPat<tjumptable, ADDiu_MM, GPR32>, ISA_MICROMIPS;
|
||||
def : WrapperPat<tglobaltlsaddr, ADDiu_MM, GPR32>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(and GPRMM16:$src, immZExtAndi16:$imm),
|
||||
(ANDI16_MM GPRMM16:$src, immZExtAndi16:$imm)>;
|
||||
def : MipsPat<(and GPR32:$src, immZExt16:$imm),
|
||||
(ANDi_MM GPR32:$src, immZExt16:$imm)>;
|
||||
def : MipsPat<(atomic_load_8 addr:$a), (LB_MM addr:$a)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(atomic_load_16 addr:$a), (LH_MM addr:$a)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(atomic_load_32 addr:$a), (LW_MM addr:$a)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(shl GPRMM16:$src, immZExt2Shift:$imm),
|
||||
(SLL16_MM GPRMM16:$src, immZExt2Shift:$imm)>;
|
||||
def : MipsPat<(shl GPR32:$src, immZExt5:$imm),
|
||||
(SLL_MM GPR32:$src, immZExt5:$imm)>;
|
||||
def : MipsPat<(shl GPR32:$lhs, GPR32:$rhs),
|
||||
(SLLV_MM GPR32:$lhs, GPR32:$rhs)>;
|
||||
def : MipsPat<(i32 immLi16:$imm),
|
||||
(LI16_MM immLi16:$imm)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(srl GPRMM16:$src, immZExt2Shift:$imm),
|
||||
(SRL16_MM GPRMM16:$src, immZExt2Shift:$imm)>;
|
||||
def : MipsPat<(srl GPR32:$src, immZExt5:$imm),
|
||||
(SRL_MM GPR32:$src, immZExt5:$imm)>;
|
||||
def : MipsPat<(srl GPR32:$lhs, GPR32:$rhs),
|
||||
(SRLV_MM GPR32:$lhs, GPR32:$rhs)>;
|
||||
defm : MaterializeImms<i32, ZERO, ADDiu_MM, LUi_MM, ORi_MM>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(sra GPR32:$src, immZExt5:$imm),
|
||||
(SRA_MM GPR32:$src, immZExt5:$imm)>;
|
||||
def : MipsPat<(sra GPR32:$lhs, GPR32:$rhs),
|
||||
(SRAV_MM GPR32:$lhs, GPR32:$rhs)>;
|
||||
def : MipsPat<(not GPRMM16:$in),
|
||||
(NOT16_MM GPRMM16:$in)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(not GPR32:$in),
|
||||
(NOR_MM GPR32Opnd:$in, ZERO)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(store GPRMM16:$src, addrimm4lsl2:$addr),
|
||||
(SW16_MM GPRMM16:$src, addrimm4lsl2:$addr)>;
|
||||
def : MipsPat<(store GPR32:$src, addr:$addr),
|
||||
(SW_MM GPR32:$src, addr:$addr)>;
|
||||
def : MipsPat<(add GPRMM16:$src, immSExtAddiur2:$imm),
|
||||
(ADDIUR2_MM GPRMM16:$src, immSExtAddiur2:$imm)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(add GPR32:$src, immSExtAddius5:$imm),
|
||||
(ADDIUS5_MM GPR32:$src, immSExtAddius5:$imm)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(add GPR32:$src, immSExt16:$imm),
|
||||
(ADDiu_MM GPR32:$src, immSExt16:$imm)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(load addrimm4lsl2:$addr),
|
||||
(LW16_MM addrimm4lsl2:$addr)>;
|
||||
def : MipsPat<(load addr:$addr),
|
||||
(LW_MM addr:$addr)>;
|
||||
def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
|
||||
(SUBu_MM GPR32:$lhs, GPR32:$rhs)>;
|
||||
def : MipsPat<(and GPRMM16:$src, immZExtAndi16:$imm),
|
||||
(ANDI16_MM GPRMM16:$src, immZExtAndi16:$imm)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(and GPR32:$src, immZExt16:$imm),
|
||||
(ANDi_MM GPR32:$src, immZExt16:$imm)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu_MM addr:$src)>,
|
||||
ISA_MICROMIPS;
|
||||
def : MipsPat<(shl GPRMM16:$src, immZExt2Shift:$imm),
|
||||
(SLL16_MM GPRMM16:$src, immZExt2Shift:$imm)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(shl GPR32:$src, immZExt5:$imm),
|
||||
(SLL_MM GPR32:$src, immZExt5:$imm)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(shl GPR32:$lhs, GPR32:$rhs),
|
||||
(SLLV_MM GPR32:$lhs, GPR32:$rhs)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu_MM addr:$src)>,
|
||||
ISA_MICROMIPS;
|
||||
def : MipsPat<(srl GPRMM16:$src, immZExt2Shift:$imm),
|
||||
(SRL16_MM GPRMM16:$src, immZExt2Shift:$imm)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(srl GPR32:$src, immZExt5:$imm),
|
||||
(SRL_MM GPR32:$src, immZExt5:$imm)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(srl GPR32:$lhs, GPR32:$rhs),
|
||||
(SRLV_MM GPR32:$lhs, GPR32:$rhs)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu_MM addr:$src)>,
|
||||
ISA_MICROMIPS;
|
||||
def : MipsPat<(sra GPR32:$src, immZExt5:$imm),
|
||||
(SRA_MM GPR32:$src, immZExt5:$imm)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(sra GPR32:$lhs, GPR32:$rhs),
|
||||
(SRAV_MM GPR32:$lhs, GPR32:$rhs)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(store GPRMM16:$src, addrimm4lsl2:$addr),
|
||||
(SW16_MM GPRMM16:$src, addrimm4lsl2:$addr)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(store GPR32:$src, addr:$addr),
|
||||
(SW_MM GPR32:$src, addr:$addr)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(load addrimm4lsl2:$addr),
|
||||
(LW16_MM addrimm4lsl2:$addr)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(load addr:$addr),
|
||||
(LW_MM addr:$addr)>, ISA_MICROMIPS;
|
||||
def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
|
||||
(SUBu_MM GPR32:$lhs, GPR32:$rhs)>, ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu_MM addr:$src)>,
|
||||
ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu_MM addr:$src)>,
|
||||
ISA_MICROMIPS;
|
||||
|
||||
def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu_MM addr:$src)>,
|
||||
ISA_MICROMIPS;
|
||||
|
||||
let AddedComplexity = 40 in
|
||||
def : MipsPat<(i32 (sextloadi16 addrRegImm:$a)),
|
||||
(LH_MM addrRegImm:$a)>, ISA_MICROMIPS;
|
||||
|
||||
let AddedComplexity = 40 in
|
||||
def : MipsPat<(i32 (sextloadi16 addrRegImm:$a)),
|
||||
(LH_MM addrRegImm:$a)>, ISA_MICROMIPS;
|
||||
}
|
||||
|
||||
def : MipsPat<(bswap GPR32:$rt), (ROTR_MM (WSBH_MM GPR32:$rt), 16)>,
|
||||
ISA_MICROMIPS;
|
||||
|
|
|
@ -3016,33 +3016,34 @@ multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
|
|||
(Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
|
||||
}
|
||||
|
||||
defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>;
|
||||
|
||||
def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
|
||||
def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>;
|
||||
|
||||
// gp_rel relocs
|
||||
def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
|
||||
(ADDiu GPR32:$gp, tglobaladdr:$in)>, ABI_NOT_N64;
|
||||
def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
|
||||
(ADDiu GPR32:$gp, tconstpool:$in)>, ABI_NOT_N64;
|
||||
|
||||
// wrapper_pic
|
||||
class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
|
||||
MipsPat<(MipsWrapper RC:$gp, node:$in),
|
||||
(ADDiuOp RC:$gp, node:$in)>;
|
||||
|
||||
def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
|
||||
def : WrapperPat<tconstpool, ADDiu, GPR32>;
|
||||
def : WrapperPat<texternalsym, ADDiu, GPR32>;
|
||||
def : WrapperPat<tblockaddress, ADDiu, GPR32>;
|
||||
def : WrapperPat<tjumptable, ADDiu, GPR32>;
|
||||
def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
|
||||
|
||||
let AdditionalPredicates = [NotInMicroMips] in {
|
||||
// Mips does not have "not", so we expand our way
|
||||
def : MipsPat<(not GPR32:$in),
|
||||
(NOR GPR32Opnd:$in, ZERO)>;
|
||||
defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
|
||||
|
||||
def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
|
||||
def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
|
||||
ISA_MIPS1;
|
||||
|
||||
// gp_rel relocs
|
||||
def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
|
||||
(ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
|
||||
def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
|
||||
(ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
|
||||
|
||||
// wrapper_pic
|
||||
class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
|
||||
MipsPat<(MipsWrapper RC:$gp, node:$in),
|
||||
(ADDiuOp RC:$gp, node:$in)>;
|
||||
|
||||
def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
|
||||
def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
|
||||
def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
|
||||
def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
|
||||
def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
|
||||
def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
|
||||
|
||||
// Mips does not have "not", so we expand our way
|
||||
def : MipsPat<(not GPR32:$in),
|
||||
(NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
|
||||
}
|
||||
|
||||
// extended loads
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
; RUN: llc -march=mips < %s -debug 2>&1 | FileCheck %s --check-prefix=MIPS
|
||||
; RUN: llc -march=mips -relocation-model=pic -mxgot < %s -debug 2>&1 | FileCheck %s --check-prefix=MIPS-XGOT
|
||||
|
||||
; RUN: llc -march=mips -mattr=+micromips < %s -debug 2>&1 | FileCheck %s --check-prefix=MM
|
||||
; RUN: llc -march=mips -relocation-model=pic -mxgot -mattr=+micromips < %s -debug 2>&1 | FileCheck %s --check-prefix=MM-XGOT
|
||||
|
||||
; REQUIRES: asserts
|
||||
|
||||
; Tests that the correct ISA is selected for computing a global address.
|
||||
|
||||
@x = global i32 0
|
||||
@a = global i32 1
|
||||
declare i32 @y(i32*, i32)
|
||||
|
||||
define i32 @z() {
|
||||
entry:
|
||||
%0 = load i32, i32* @a, align 4
|
||||
%1 = call i32 @y(i32 * @x, i32 %0)
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
; MIPS-LABEL: ===== Instruction selection ends:
|
||||
; MIPS: t[[A:[0-9]+]]: i32 = LUi TargetGlobalAddress:i32<i32* @x> 0 [TF=4]
|
||||
; MIPS: t{{.*}}: i32 = ADDiu t[[A]], TargetGlobalAddress:i32<i32* @x> 0 [TF=5]
|
||||
|
||||
; MIPS-XGOT-LABEL: ===== Instruction selection ends:
|
||||
; MIPS-XGOT: t[[B:[0-9]+]]: i32 = LUi TargetGlobalAddress:i32<i32* @x> 0 [TF=20]
|
||||
; MIPS-XGOT: t[[C:[0-9]+]]: i32 = ADDu t[[B]], Register:i32 %0
|
||||
; MIPS-XGOT: t{{.*}}: i32,ch = LW<Mem:(load 4 from got)> t[[C]], TargetGlobalAddress:i32<i32* @x> 0 [TF=21], t{{.*}}
|
||||
|
||||
; MM-LABEL: ===== Instruction selection ends:
|
||||
; MM: t[[A:[0-9]+]]: i32 = LUi_MM TargetGlobalAddress:i32<i32* @x> 0 [TF=4]
|
||||
; MM: t{{.*}}: i32 = ADDiu_MM t[[A]], TargetGlobalAddress:i32<i32* @x> 0 [TF=5]
|
||||
|
||||
; MM-XGOT-LABEL: ===== Instruction selection ends:
|
||||
; MM-XGOT: t[[B:[0-9]+]]: i32 = LUi_MM TargetGlobalAddress:i32<i32* @x> 0 [TF=20]
|
||||
; MM-XGOT: t[[C:[0-9]+]]: i32 = ADDU16_MM t[[B]], Register:i32 %0
|
||||
; MM-XGOT: t{{.*}}: i32,ch = LW_MM<Mem:(load 4 from got)> t[[C]], TargetGlobalAddress:i32<i32* @x> 0 [TF=21], t0
|
|
@ -0,0 +1,36 @@
|
|||
; RUN: llc -march=mips < %s -debug 2>&1 | FileCheck %s --check-prefix=MIPS
|
||||
; RUN: llc -march=mips -mattr=+micromips < %s -debug 2>&1 | FileCheck %s --check-prefix=MM
|
||||
|
||||
; REQUIRES: asserts
|
||||
|
||||
; Test that the correct ISA is selected for the materialization of constants.
|
||||
|
||||
; The four parameters are picked to use these instructions: li16, addiu, lui,
|
||||
; lui+addiu.
|
||||
|
||||
declare void @e(i32)
|
||||
declare void @f(i32, i32, i32)
|
||||
define void @g() {
|
||||
entry:
|
||||
call void @f (i32 1, i32 2048, i32 8388608)
|
||||
call void @e (i32 150994946)
|
||||
ret void
|
||||
}
|
||||
|
||||
; MIPS-LABEL: ===== Instruction selection ends:
|
||||
; MIPS-DAG: t{{[0-9]+}}: i32 = ADDiu Register:i32 $zero, TargetConstant:i32<1>
|
||||
; MIPS-DAG: t{{[0-9]+}}: i32 = ADDiu Register:i32 $zero, TargetConstant:i32<2048>
|
||||
; MIPS-DAG: t{{[0-9]+}}: i32 = LUi TargetConstant:i32<128>
|
||||
; MIPS: t{{[0-9]+}}: ch,glue = JAL TargetGlobalAddress:i32<void (i32, i32, i32)* @f>
|
||||
|
||||
; MIPS: t[[A:[0-9]+]]: i32 = LUi TargetConstant:i32<2304>
|
||||
; MIPS: t{{[0-9]+}}: i32 = ORi t[[A]], TargetConstant:i32<2>
|
||||
|
||||
; MM-LABEL: ===== Instruction selection ends:
|
||||
; MM-DAG: t{{[0-9]+}}: i32 = LI16_MM TargetConstant:i32<1>
|
||||
; MM-DAG: t{{[0-9]+}}: i32 = ADDiu_MM Register:i32 $zero, TargetConstant:i32<2048>
|
||||
; MM-DAG: t{{[0-9]+}}: i32 = LUi_MM TargetConstant:i32<128>
|
||||
; MM: t{{[0-9]+}}: ch,glue = JAL_MM TargetGlobalAddress:i32<void (i32, i32, i32)* @f>
|
||||
|
||||
; MM: t[[A:[0-9]+]]: i32 = LUi_MM TargetConstant:i32<2304>
|
||||
; MM: t{{[0-9]+}}: i32 = ORi_MM t[[A]], TargetConstant:i32<2>
|
Loading…
Reference in New Issue