From 27185190e6652d4c6d70bdf1202a518e5d3f3053 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 29 Sep 2006 21:20:16 +0000 Subject: [PATCH] add floating point registers implement SINT_TO_FP git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30673 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelDAGToDAG.cpp | 32 +++++++-- lib/Target/ARM/ARMInstrInfo.td | 16 +++++ lib/Target/ARM/ARMRegisterInfo.td | 112 ++++++++++++++++++++++++----- test/CodeGen/ARM/fp.ll | 10 +++ 4 files changed, 147 insertions(+), 23 deletions(-) create mode 100644 test/CodeGen/ARM/fp.ll diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 8c9cf27fc76..a98064cc2f7 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -45,9 +45,10 @@ namespace { ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) : TargetLowering(TM) { addRegisterClass(MVT::i32, ARM::IntRegsRegisterClass); + addRegisterClass(MVT::f32, ARM::FPRegsRegisterClass); + addRegisterClass(MVT::f64, ARM::DFPRegsRegisterClass); - //LLVM requires that a register class supports MVT::f64! - addRegisterClass(MVT::f64, ARM::IntRegsRegisterClass); + setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); setOperationAction(ISD::RET, MVT::Other, Custom); setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); @@ -79,7 +80,9 @@ namespace llvm { SELECT, - BR + BR, + + FSITOS }; } } @@ -111,6 +114,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { case ARMISD::SELECT: return "ARMISD::SELECT"; case ARMISD::CMP: return "ARMISD::CMP"; case ARMISD::BR: return "ARMISD::BR"; + case ARMISD::FSITOS: return "ARMISD::FSITOS"; } } @@ -241,11 +245,18 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { SDOperand LR = DAG.getRegister(ARM::R14, MVT::i32); return DAG.getNode(ARMISD::RET_FLAG, MVT::Other, Chain); } - case 3: - Copy = DAG.getCopyToReg(Chain, ARM::R0, Op.getOperand(1), SDOperand()); + case 3: { + SDOperand Val = Op.getOperand(1); + assert(Val.getValueType() == MVT::i32 || + Val.getValueType() == MVT::f32); + + if (Val.getValueType() == MVT::f32) + Val = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Val); + Copy = DAG.getCopyToReg(Chain, ARM::R0, Val, SDOperand()); if (DAG.getMachineFunction().liveout_empty()) DAG.getMachineFunction().addLiveOut(ARM::R0); break; + } case 5: Copy = DAG.getCopyToReg(Chain, ARM::R1, Op.getOperand(3), SDOperand()); Copy = DAG.getCopyToReg(Copy, ARM::R0, Op.getOperand(1), Copy.getValue(1)); @@ -409,6 +420,15 @@ static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(ARMISD::BR, MVT::Other, Chain, Dest, ARMCC, Cmp); } +static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) { + SDOperand IntVal = Op.getOperand(0); + assert(IntVal.getValueType() == MVT::i32); + assert(Op.getValueType() == MVT::f32); + + SDOperand Tmp = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, IntVal); + return DAG.getNode(ARMISD::FSITOS, MVT::f32, Tmp); +} + SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { default: @@ -418,6 +438,8 @@ SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return LowerConstantPool(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); + case ISD::SINT_TO_FP: + return LowerSINT_TO_FP(Op, DAG); case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex); case ISD::CALL: diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 50f4650fdfe..0253947c4cf 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -74,6 +74,8 @@ def armbr : SDNode<"ARMISD::BR", SDTarmbr, [SDNPHasChain, SDNPInFlag]>; def SDTVoidBinOp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; def armcmp : SDNode<"ARMISD::CMP", SDTVoidBinOp, [SDNPOutFlag]>; +def armfsitos : SDNode<"ARMISD::FSITOS", SDTUnaryOp>; + def ADJCALLSTACKUP : InstARM<(ops i32imm:$amt), "!ADJCALLSTACKUP $amt", [(callseq_end imm:$amt)]>; @@ -150,3 +152,17 @@ def b : InstARM<(ops brtarget:$dst), def cmp : InstARM<(ops IntRegs:$a, op_addr_mode1:$b), "cmp $a, $b", [(armcmp IntRegs:$a, addr_mode1:$b)]>; + + +// Floating Point Conversion +// We use bitconvert for moving the data between the register classes. +// The format conversion is done with ARM specific nodes + +def FMSR : InstARM<(ops FPRegs:$dst, IntRegs:$src), + "fmsr $dst, $src", [(set FPRegs:$dst, (bitconvert IntRegs:$src))]>; + +def FMRS : InstARM<(ops IntRegs:$dst, FPRegs:$src), + "fmrs $dst, $src", [(set IntRegs:$dst, (bitconvert FPRegs:$src))]>; + +def FSITOS : InstARM<(ops FPRegs:$dst, FPRegs:$src), + "fsitos $dst, $src", [(set FPRegs:$dst, (armfsitos FPRegs:$src))]>; diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index 89a84f59274..143b953508b 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -13,28 +13,97 @@ //===----------------------------------------------------------------------===// // Registers are identified with 4-bit ID numbers. -class ARMReg num, string n> : Register { - field bits<4> Num; +class ARMReg : Register { let Namespace = "ARM"; } +// Ri - 32-bit integer registers +class Ri num, string n> : ARMReg { + field bits<4> Num; + let Num = num; +} +// Rf - 32-bit floating-point registers +class Rf num, string n> : ARMReg { + field bits<5> Num; + let Num = num; +} +// Rd - Slots in the FP register file for 64-bit floating-point values. +class Rd num, string n, list aliases> : ARMReg { + field bits<5> Num; + let Num = num; + let Aliases = aliases; +} + // Integer registers -def R0 : ARMReg< 0, "R0">, DwarfRegNum<0>; -def R1 : ARMReg< 1, "R1">, DwarfRegNum<1>; -def R2 : ARMReg< 2, "R2">, DwarfRegNum<2>; -def R3 : ARMReg< 3, "R3">, DwarfRegNum<3>; -def R4 : ARMReg< 4, "R4">, DwarfRegNum<4>; -def R5 : ARMReg< 5, "R5">, DwarfRegNum<5>; -def R6 : ARMReg< 6, "R6">, DwarfRegNum<6>; -def R7 : ARMReg< 7, "R7">, DwarfRegNum<7>; -def R8 : ARMReg< 8, "R8">, DwarfRegNum<8>; -def R9 : ARMReg< 9, "R9">, DwarfRegNum<9>; -def R10 : ARMReg<10, "R10">, DwarfRegNum<10>; -def R11 : ARMReg<11, "R11">, DwarfRegNum<11>; -def R12 : ARMReg<12, "R12">, DwarfRegNum<12>; -def R13 : ARMReg<13, "R13">, DwarfRegNum<13>; -def R14 : ARMReg<14, "R14">, DwarfRegNum<14>; -def R15 : ARMReg<15, "R15">, DwarfRegNum<15>; +def R0 : Ri< 0, "R0">, DwarfRegNum<0>; +def R1 : Ri< 1, "R1">, DwarfRegNum<1>; +def R2 : Ri< 2, "R2">, DwarfRegNum<2>; +def R3 : Ri< 3, "R3">, DwarfRegNum<3>; +def R4 : Ri< 4, "R4">, DwarfRegNum<4>; +def R5 : Ri< 5, "R5">, DwarfRegNum<5>; +def R6 : Ri< 6, "R6">, DwarfRegNum<6>; +def R7 : Ri< 7, "R7">, DwarfRegNum<7>; +def R8 : Ri< 8, "R8">, DwarfRegNum<8>; +def R9 : Ri< 9, "R9">, DwarfRegNum<9>; +def R10 : Ri<10, "R10">, DwarfRegNum<10>; +def R11 : Ri<11, "R11">, DwarfRegNum<11>; +def R12 : Ri<12, "R12">, DwarfRegNum<12>; +def R13 : Ri<13, "R13">, DwarfRegNum<13>; +def R14 : Ri<14, "R14">, DwarfRegNum<14>; +def R15 : Ri<15, "R15">, DwarfRegNum<15>; + +// TODO: update to VFP-v3 +// Floating-point registers +def S0 : Rf< 0, "S0">, DwarfRegNum<64>; +def S1 : Rf< 1, "S1">, DwarfRegNum<65>; +def S2 : Rf< 2, "S2">, DwarfRegNum<66>; +def S3 : Rf< 3, "S3">, DwarfRegNum<67>; +def S4 : Rf< 4, "S4">, DwarfRegNum<68>; +def S5 : Rf< 5, "S5">, DwarfRegNum<69>; +def S6 : Rf< 6, "S6">, DwarfRegNum<70>; +def S7 : Rf< 7, "S7">, DwarfRegNum<71>; +def S8 : Rf< 8, "S8">, DwarfRegNum<72>; +def S9 : Rf< 9, "S9">, DwarfRegNum<73>; +def S10 : Rf<10, "S10">, DwarfRegNum<74>; +def S11 : Rf<11, "S11">, DwarfRegNum<75>; +def S12 : Rf<12, "S12">, DwarfRegNum<76>; +def S13 : Rf<13, "S13">, DwarfRegNum<77>; +def S14 : Rf<14, "S14">, DwarfRegNum<78>; +def S15 : Rf<15, "S15">, DwarfRegNum<79>; +def S16 : Rf<16, "S16">, DwarfRegNum<80>; +def S17 : Rf<17, "S17">, DwarfRegNum<81>; +def S18 : Rf<18, "S18">, DwarfRegNum<82>; +def S19 : Rf<19, "S19">, DwarfRegNum<83>; +def S20 : Rf<20, "S20">, DwarfRegNum<84>; +def S21 : Rf<21, "S21">, DwarfRegNum<85>; +def S22 : Rf<22, "S22">, DwarfRegNum<86>; +def S23 : Rf<23, "S23">, DwarfRegNum<87>; +def S24 : Rf<24, "S24">, DwarfRegNum<88>; +def S25 : Rf<25, "S25">, DwarfRegNum<89>; +def S26 : Rf<26, "S26">, DwarfRegNum<90>; +def S27 : Rf<27, "S27">, DwarfRegNum<91>; +def S28 : Rf<28, "S28">, DwarfRegNum<92>; +def S29 : Rf<29, "S29">, DwarfRegNum<93>; +def S30 : Rf<30, "S30">, DwarfRegNum<94>; +def S31 : Rf<31, "S31">, DwarfRegNum<95>; + +// Aliases of the S* registers used to hold 64-bit fp values (doubles) +def D0 : Rd< 0, "S0", [S0, S1]>, DwarfRegNum<64>; +def D1 : Rd< 2, "S2", [S2, S3]>, DwarfRegNum<66>; +def D2 : Rd< 4, "S4", [S4, S5]>, DwarfRegNum<68>; +def D3 : Rd< 6, "S6", [S6, S7]>, DwarfRegNum<70>; +def D4 : Rd< 8, "S8", [S8, S9]>, DwarfRegNum<72>; +def D5 : Rd<10, "S10", [S10, S11]>, DwarfRegNum<74>; +def D6 : Rd<12, "S12", [S12, S13]>, DwarfRegNum<76>; +def D7 : Rd<14, "S14", [S14, S15]>, DwarfRegNum<78>; +def D8 : Rd<16, "S16", [S16, S17]>, DwarfRegNum<80>; +def D9 : Rd<18, "S18", [S18, S19]>, DwarfRegNum<82>; +def D10 : Rd<20, "S20", [S20, S21]>, DwarfRegNum<84>; +def D11 : Rd<22, "S22", [S22, S23]>, DwarfRegNum<86>; +def D12 : Rd<24, "S24", [S24, S25]>, DwarfRegNum<88>; +def D13 : Rd<26, "S26", [S26, S27]>, DwarfRegNum<90>; +def D14 : Rd<28, "S28", [S28, S29]>, DwarfRegNum<92>; +def D15 : Rd<30, "S30", [S30, S31]>, DwarfRegNum<94>; // Register classes. // @@ -60,3 +129,10 @@ def IntRegs : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, } }]; } + +def FPRegs : RegisterClass<"ARM", [f32], 32, [S0, S1, S2, S3, S4, S5, S6, S7, S8, + S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, S20, S21, S22, + S23, S24, S25, S26, S27, S28, S29, S30, S31]>; + +def DFPRegs : RegisterClass<"ARM", [f64], 64, [D0, D1, D2, D3, D4, D5, D6, D7, + D8, D9, D10, D11, D12, D13, D14, D15]>; diff --git a/test/CodeGen/ARM/fp.ll b/test/CodeGen/ARM/fp.ll new file mode 100644 index 00000000000..60e96f0414e --- /dev/null +++ b/test/CodeGen/ARM/fp.ll @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llc -march=arm && +; RUN: llvm-as < %s | llc -march=arm | grep fmsr && +; RUN: llvm-as < %s | llc -march=arm | grep fsitos && +; RUN: llvm-as < %s | llc -march=arm | grep fmrs + +float %f(int %a) { +entry: + %tmp = cast int %a to float ; [#uses=1] + ret float %tmp +} -- 2.34.1