diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index a43bc0bb818..8e40668b2fa 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -2268,6 +2268,9 @@ SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op, static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State, const MCPhysReg *F64Regs) { + const MipsSubtarget &Subtarget = + State.getMachineFunction().getTarget() + .getSubtarget(); static const unsigned IntRegsSize = 4, FloatRegsSize = 2; @@ -2278,6 +2281,19 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, if (ArgFlags.isByVal()) return true; + // Promote i8 and i16 + if (ArgFlags.isInReg() && !Subtarget.isLittle()) { + if (LocVT == MVT::i8 || LocVT == MVT::i16 || LocVT == MVT::i32) { + LocVT = MVT::i32; + if (ArgFlags.isSExt()) + LocInfo = CCValAssign::SExtUpper; + else if (ArgFlags.isZExt()) + LocInfo = CCValAssign::ZExtUpper; + else + LocInfo = CCValAssign::AExtUpper; + } + } + // Promote i8 and i16 if (LocVT == MVT::i8 || LocVT == MVT::i16) { LocVT = MVT::i32; diff --git a/test/CodeGen/Mips/cconv/arguments-struct.ll b/test/CodeGen/Mips/cconv/arguments-struct.ll new file mode 100644 index 00000000000..16cf1808bb5 --- /dev/null +++ b/test/CodeGen/Mips/cconv/arguments-struct.ll @@ -0,0 +1,41 @@ +; RUN: llc -march=mips -relocation-model=static < %s | FileCheck --check-prefix=ALL --check-prefix=SYM32 --check-prefix=O32-BE %s +; RUN: llc -march=mipsel -relocation-model=static < %s | FileCheck --check-prefix=ALL --check-prefix=SYM32 --check-prefix=O32-LE %s + +; RUN-TODO: llc -march=mips64 -relocation-model=static -mattr=-n64,+o32 < %s | FileCheck --check-prefix=ALL --check-prefix=SYM32 --check-prefix=O32-BE %s +; RUN-TODO: llc -march=mips64el -relocation-model=static -mattr=-n64,+o32 < %s | FileCheck --check-prefix=ALL --check-prefix=SYM32 --check-prefix=O32-LE %s + +; RUN: llc -march=mips64 -relocation-model=static -mattr=-n64,+n32 < %s | FileCheck --check-prefix=ALL --check-prefix=SYM32 --check-prefix=NEW-BE %s +; RUN: llc -march=mips64el -relocation-model=static -mattr=-n64,+n32 < %s | FileCheck --check-prefix=ALL --check-prefix=SYM32 --check-prefix=NEW-LE %s + +; RUN: llc -march=mips64 -relocation-model=static -mattr=-n64,+n64 < %s | FileCheck --check-prefix=ALL --check-prefix=SYM64 --check-prefix=NEW-BE %s +; RUN: llc -march=mips64el -relocation-model=static -mattr=-n64,+n64 < %s | FileCheck --check-prefix=ALL --check-prefix=SYM64 --check-prefix=NEW-LE %s + +; Test small structures for all ABI's and byte orders. +; +; N32/N64 are identical in this area so their checks have been combined into +; the 'NEW' prefix (the N stands for New). + +@bytes = global [2 x i8] zeroinitializer + +define void @s_i8(i8 inreg %a) nounwind { +entry: + store i8 %a, i8* getelementptr inbounds ([2 x i8]* @bytes, i32 0, i32 1) + ret void +} + +; ALL-LABEL: s_i8: + +; SYM32-DAG: lui [[PTR_HI:\$[0-9]+]], %hi(bytes) +; SYM32-DAG: addiu [[PTR:\$[0-9]+]], [[PTR_HI]], %lo(bytes) + +; SYM64-DAG: ld [[PTR:\$[0-9]+]], %got_disp(bytes)( + +; O32-BE-DAG: srl [[ARG:\$[0-9]+]], $4, 24 +; O32-BE-DAG: sb [[ARG]], 1([[PTR]]) + +; O32-LE-DAG: sb $4, 1([[PTR]]) + +; NEW-BE-DAG: dsrl [[ARG:\$[0-9]+]], $4, 56 +; NEW-BE-DAG: sb [[ARG]], 1([[PTR]]) + +; NEW-LE-DAG: sb $4, 1([[PTR]])