mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
[mips][FastISel] Implement the select statement for MIPS FastISel.
Summary: Implement the LLVM IR select statement for MIPS FastISelsel. Based on a patch by Reed Kotler. Test Plan: "Make check" test included now. Passes test-suite at O2/O0 mips32 r1/r2. Reviewers: dsanders, rkotler Subscribers: llvm-commits, rfuhler Differential Revision: http://reviews.llvm.org/D6774 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238756 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
30b5412d92
commit
e490b7733a
@ -94,6 +94,7 @@ private:
|
||||
bool selectLoad(const Instruction *I);
|
||||
bool selectStore(const Instruction *I);
|
||||
bool selectBranch(const Instruction *I);
|
||||
bool selectSelect(const Instruction *I);
|
||||
bool selectCmp(const Instruction *I);
|
||||
bool selectFPExt(const Instruction *I);
|
||||
bool selectFPTrunc(const Instruction *I);
|
||||
@ -899,6 +900,50 @@ bool MipsFastISel::selectFPExt(const Instruction *I) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsFastISel::selectSelect(const Instruction *I) {
|
||||
assert(isa<SelectInst>(I) && "Expected a select instruction.");
|
||||
|
||||
MVT VT;
|
||||
if (!isTypeSupported(I->getType(), VT))
|
||||
return false;
|
||||
|
||||
unsigned CondMovOpc;
|
||||
const TargetRegisterClass *RC;
|
||||
|
||||
if (VT.isInteger() && !VT.isVector() && VT.getSizeInBits() <= 32) {
|
||||
CondMovOpc = Mips::MOVN_I_I;
|
||||
RC = &Mips::GPR32RegClass;
|
||||
} else if (VT == MVT::f32) {
|
||||
CondMovOpc = Mips::MOVN_I_S;
|
||||
RC = &Mips::FGR32RegClass;
|
||||
} else if (VT == MVT::f64) {
|
||||
CondMovOpc = Mips::MOVN_I_D32;
|
||||
RC = &Mips::AFGR64RegClass;
|
||||
} else
|
||||
return false;
|
||||
|
||||
const SelectInst *SI = cast<SelectInst>(I);
|
||||
const Value *Cond = SI->getCondition();
|
||||
unsigned Src1Reg = getRegForValue(SI->getTrueValue());
|
||||
unsigned Src2Reg = getRegForValue(SI->getFalseValue());
|
||||
unsigned CondReg = getRegForValue(Cond);
|
||||
|
||||
if (!Src1Reg || !Src2Reg || !CondReg)
|
||||
return false;
|
||||
|
||||
unsigned ResultReg = createResultReg(RC);
|
||||
unsigned TempReg = createResultReg(RC);
|
||||
|
||||
if (!ResultReg || !TempReg)
|
||||
return false;
|
||||
|
||||
emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
|
||||
emitInst(CondMovOpc, ResultReg)
|
||||
.addReg(Src1Reg).addReg(CondReg).addReg(TempReg);
|
||||
updateValueMap(I, ResultReg);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Attempt to fast-select a floating-point truncate instruction.
|
||||
bool MipsFastISel::selectFPTrunc(const Instruction *I) {
|
||||
if (UnsupportedFPMode)
|
||||
@ -1539,6 +1584,8 @@ bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
|
||||
case Instruction::ICmp:
|
||||
case Instruction::FCmp:
|
||||
return selectCmp(I);
|
||||
case Instruction::Select:
|
||||
return selectSelect(I);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
91
test/CodeGen/Mips/Fast-ISel/sel1.ll
Normal file
91
test/CodeGen/Mips/Fast-ISel/sel1.ll
Normal file
@ -0,0 +1,91 @@
|
||||
; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O2 -relocation-model=pic \
|
||||
; RUN: -fast-isel -mips-fast-isel -fast-isel-abort=1 | FileCheck %s
|
||||
|
||||
define i1 @sel_i1(i1 %j, i1 %k, i1 %l) {
|
||||
entry:
|
||||
; CHECK-LABEL: sel_i1:
|
||||
|
||||
; FIXME: The following instruction is redundant.
|
||||
; CHECK: xor $[[T0:[0-9]+]], $4, $zero
|
||||
; CHECK-NEXT: sltu $[[T1:[0-9]+]], $zero, $[[T0]]
|
||||
; CHECK-NEXT: movn $6, $5, $[[T1]]
|
||||
; CHECK: move $2, $6
|
||||
%cond = icmp ne i1 %j, 0
|
||||
%res = select i1 %cond, i1 %k, i1 %l
|
||||
ret i1 %res
|
||||
}
|
||||
|
||||
define i8 @sel_i8(i8 %j, i8 %k, i8 %l) {
|
||||
entry:
|
||||
; CHECK-LABEL: sel_i8:
|
||||
|
||||
; CHECK-DAG: seb $[[T0:[0-9]+]], $4
|
||||
; FIXME: The following 2 instructions are redundant.
|
||||
; CHECK-DAG: seb $[[T1:[0-9]+]], $zero
|
||||
; CHECK: xor $[[T2:[0-9]+]], $[[T0]], $[[T1]]
|
||||
; CHECK-NEXT: sltu $[[T3:[0-9]+]], $zero, $[[T2]]
|
||||
; CHECK-NEXT: movn $6, $5, $[[T3]]
|
||||
; CHECK: move $2, $6
|
||||
%cond = icmp ne i8 %j, 0
|
||||
%res = select i1 %cond, i8 %k, i8 %l
|
||||
ret i8 %res
|
||||
}
|
||||
|
||||
define i16 @sel_i16(i16 %j, i16 %k, i16 %l) {
|
||||
entry:
|
||||
; CHECK-LABEL: sel_i16:
|
||||
|
||||
; CHECK-DAG: seh $[[T0:[0-9]+]], $4
|
||||
; FIXME: The following 2 instructions are redundant.
|
||||
; CHECK-DAG: seh $[[T1:[0-9]+]], $zero
|
||||
; CHECK: xor $[[T2:[0-9]+]], $[[T0]], $[[T1]]
|
||||
; CHECK-NEXT: sltu $[[T3:[0-9]+]], $zero, $[[T2]]
|
||||
; CHECK-NEXT: movn $6, $5, $[[T3]]
|
||||
; CHECK: move $2, $6
|
||||
%cond = icmp ne i16 %j, 0
|
||||
%res = select i1 %cond, i16 %k, i16 %l
|
||||
ret i16 %res
|
||||
}
|
||||
|
||||
define i32 @sel_i32(i32 %j, i32 %k, i32 %l) {
|
||||
entry:
|
||||
; CHECK-LABEL: sel_i32:
|
||||
|
||||
; FIXME: The following instruction is redundant.
|
||||
; CHECK: xor $[[T0:[0-9]+]], $4, $zero
|
||||
; CHECK-NEXT: sltu $[[T1:[0-9]+]], $zero, $[[T0]]
|
||||
; CHECK-NEXT: movn $6, $5, $[[T1]]
|
||||
; CHECK: move $2, $6
|
||||
%cond = icmp ne i32 %j, 0
|
||||
%res = select i1 %cond, i32 %k, i32 %l
|
||||
ret i32 %res
|
||||
}
|
||||
|
||||
define float @sel_float(i32 %j, float %k, float %l) {
|
||||
entry:
|
||||
; CHECK-LABEL: sel_float:
|
||||
|
||||
; CHECK-DAG: mtc1 $6, $f0
|
||||
; CHECK-DAG: mtc1 $5, $f1
|
||||
; CHECK-DAG: xor $[[T0:[0-9]+]], $4, $zero
|
||||
; CHECK: sltu $[[T1:[0-9]+]], $zero, $[[T0]]
|
||||
; CHECK: movn.s $f0, $f1, $[[T1]]
|
||||
%cond = icmp ne i32 %j, 0
|
||||
%res = select i1 %cond, float %k, float %l
|
||||
ret float %res
|
||||
}
|
||||
|
||||
define double @sel_double(i32 %j, double %k, double %l) {
|
||||
entry:
|
||||
; CHECK-LABEL: sel_double:
|
||||
|
||||
; CHECK-DAG: mtc1 $6, $f2
|
||||
; CHECK-DAG: mthc1 $7, $f2
|
||||
; CHECK-DAG: ldc1 $f0, 16($sp)
|
||||
; CHECK-DAG: xor $[[T0:[0-9]+]], $4, $zero
|
||||
; CHECK: sltu $[[T1:[0-9]+]], $zero, $[[T0]]
|
||||
; CHECK: movn.d $f0, $f2, $[[T1]]
|
||||
%cond = icmp ne i32 %j, 0
|
||||
%res = select i1 %cond, double %k, double %l
|
||||
ret double %res
|
||||
}
|
Loading…
Reference in New Issue
Block a user