Summary: Allow Mips fast-isel to handle functions which return i8/i16 signed/unsigned.
Test Plan:
Make check tests are forthcoming.
Already passes test-suite at O0/O2 for Mips 32 r1/r2
Reviewers: dsanders, rkotler
Subscribers: llvm-commits, rfuhler
Differential Revision: http://reviews.llvm.org/D6765
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236103
91177308-0d34-0410-b5e6-
96231b3b80d8
// Only the return rules are defined here for O32. The rules for argument
// passing are defined in MipsISelLowering.cpp.
def RetCC_MipsO32 : CallingConv<[
+ // Promote i1/i8/i16 return values to i32.
+ CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
+
// i32 are returned in registers V0, V1, A0, A1
CCIfType<[i32], CCAssignToReg<[V0, V1, A0, A1]>>,
CopyVT = MVT::i32;
unsigned ResultReg = createResultReg(TLI.getRegClassFor(CopyVT));
+ if (!ResultReg)
+ return false;
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::COPY),
ResultReg).addReg(RVLocs[0].getLocReg());
MVT RetVT;
if (CLI.RetTy->isVoidTy())
RetVT = MVT::isVoid;
- else if (!isTypeLegal(CLI.RetTy, RetVT))
+ else if (!isTypeSupported(CLI.RetTy, RetVT))
return false;
for (auto Flag : CLI.OutFlags)
if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
return false;
- if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt())
- return false;
-
- bool IsZExt = Outs[0].Flags.isZExt();
- SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
- if (SrcReg == 0)
- return false;
+ if (Outs[0].Flags.isZExt() || Outs[0].Flags.isSExt()) {
+ bool IsZExt = Outs[0].Flags.isZExt();
+ SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
+ if (SrcReg == 0)
+ return false;
+ }
}
// Make the copy.
; CHECK: jr $ra
}
+; Function Attrs: nounwind
+define i16 @retus() {
+entry:
+; CHECK-LABEL: retus:
+ %0 = load i16, i16* @s, align 2
+ ret i16 %0
+; CHECK: lui $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK: addiu $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK: addu $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK: lw $[[REG_S_ADDR:[0-9]+]], %got(s)($[[REG_GP]])
+; CHECK: lhu $2, 0($[[REG_S_ADDR]])
+; CHECK: jr $ra
+}
+
; Function Attrs: nounwind
define signext i16 @rets() {
entry:
; CHECK: jr $ra
}
+; Function Attrs: nounwind
+define i8 @retuc() {
+entry:
+; CHECK-LABEL: retuc:
+ %0 = load i8, i8* @c, align 1
+ ret i8 %0
+; CHECK: lui $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK: addiu $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK: addu $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK: lw $[[REG_C_ADDR:[0-9]+]], %got(c)($[[REG_GP]])
+; CHECK: lbu $2, 0($[[REG_C_ADDR]])
+; CHECK: jr $ra
+}
+
; Function Attrs: nounwind
define signext i8 @retc() {
entry: