Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -1164,75 +1164,96 @@ // 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, ISA_MICROMIPS; - defm : MaterializeImms; -} +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)>; - - 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 : 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<(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<(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)>; - - 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<(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<(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<(i32 (extloadi1 addr:$src)), (LBu_MM addr:$src)>, - ISA_MICROMIPS; +// 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 : WrapperPat, ISA_MICROMIPS; +def : WrapperPat, ISA_MICROMIPS; +def : WrapperPat, ISA_MICROMIPS; +def : WrapperPat, ISA_MICROMIPS; +def : WrapperPat, ISA_MICROMIPS; +def : WrapperPat, ISA_MICROMIPS; + +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<(i32 immLi16:$imm), + (LI16_MM immLi16:$imm)>, ISA_MICROMIPS; + +defm : MaterializeImms, ISA_MICROMIPS; + +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<(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<(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<(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<(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<(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 (extloadi8 addr:$src)), (LBu_MM addr:$src)>, + ISA_MICROMIPS; - def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu_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; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -3012,33 +3012,34 @@ (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>; } -defm : MipsHiLoRelocs; - -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: - MipsPat<(MipsWrapper RC:$gp, node:$in), - (ADDiuOp RC:$gp, node:$in)>; +let AdditionalPredicates = [NotInMicroMips] in { + defm : MipsHiLoRelocs, ISA_MIPS1; -def : WrapperPat; -def : WrapperPat; -def : WrapperPat; -def : WrapperPat; -def : WrapperPat; -def : WrapperPat; + def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1; + def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>, + ISA_MIPS1; -let AdditionalPredicates = [NotInMicroMips] in { -// Mips does not have "not", so we expand our way -def : MipsPat<(not GPR32:$in), - (NOR GPR32Opnd:$in, ZERO)>; + // 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: + MipsPat<(MipsWrapper RC:$gp, node:$in), + (ADDiuOp RC:$gp, node:$in)>; + + def : WrapperPat, ISA_MIPS1; + def : WrapperPat, ISA_MIPS1; + def : WrapperPat, ISA_MIPS1; + def : WrapperPat, ISA_MIPS1; + def : WrapperPat, ISA_MIPS1; + def : WrapperPat, 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 Index: test/CodeGen/Mips/address-selection.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/address-selection.ll @@ -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 0 [TF=4] +; MIPS: t{{.*}}: i32 = ADDiu t[[A]], TargetGlobalAddress:i32 0 [TF=5] + +; MIPS-XGOT-LABEL: ===== Instruction selection ends: +; MIPS-XGOT: t[[B:[0-9]+]]: i32 = LUi TargetGlobalAddress:i32 0 [TF=20] +; MIPS-XGOT: t[[C:[0-9]+]]: i32 = ADDu t[[B]], Register:i32 %0 +; MIPS-XGOT: t{{.*}}: i32,ch = LW t[[C]], TargetGlobalAddress:i32 0 [TF=21], t{{.*}} + +; MM-LABEL: ===== Instruction selection ends: +; MM: t[[A:[0-9]+]]: i32 = LUi_MM TargetGlobalAddress:i32 0 [TF=4] +; MM: t{{.*}}: i32 = ADDiu_MM t[[A]], TargetGlobalAddress:i32 0 [TF=5] + +; MM-XGOT-LABEL: ===== Instruction selection ends: +; MM-XGOT: t[[B:[0-9]+]]: i32 = LUi_MM TargetGlobalAddress:i32 0 [TF=20] +; MM-XGOT: t[[C:[0-9]+]]: i32 = ADDU16_MM t[[B]], Register:i32 %0 +; MM-XGOT: t{{.*}}: i32,ch = LW_MM t[[C]], TargetGlobalAddress:i32 0 [TF=21], t0 Index: test/CodeGen/Mips/cstmaterialization/isel-materialization.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/cstmaterialization/isel-materialization.ll @@ -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 + +; 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 + +; MM: t[[A:[0-9]+]]: i32 = LUi_MM TargetConstant:i32<2304> +; MM: t{{[0-9]+}}: i32 = ORi_MM t[[A]], TargetConstant:i32<2>