[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:
Simon Dardis 2018-06-20 22:40:12 +00:00
parent d1d83df807
commit 0f111dd704
4 changed files with 178 additions and 82 deletions

View File

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

View File

@ -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

View File

@ -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

View File

@ -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>