fix the names of the 64bit fp register
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 2 Oct 2006 19:30:56 +0000 (19:30 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 2 Oct 2006 19:30:56 +0000 (19:30 +0000)
initial support for returning 64bit floating point numbers

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30692 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelDAGToDAG.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMRegisterInfo.td
test/CodeGen/ARM/fp.ll

index a98064cc2f701cae63ea7d058d364c8d23491749..e4b591d675230e0af04e5e100b5bdfb91c5bff03 100644 (file)
@@ -82,7 +82,11 @@ namespace llvm {
 
       BR,
 
-      FSITOS
+      FSITOS,
+
+      FSITOD,
+
+      FMRRD
     };
   }
 }
@@ -115,6 +119,8 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
   case ARMISD::CMP:           return "ARMISD::CMP";
   case ARMISD::BR:            return "ARMISD::BR";
   case ARMISD::FSITOS:        return "ARMISD::FSITOS";
+  case ARMISD::FSITOD:        return "ARMISD::FSITOD";
+  case ARMISD::FMRRD:         return "ARMISD::FMRRD";
   }
 }
 
@@ -237,6 +243,9 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
 static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
   SDOperand Copy;
   SDOperand Chain = Op.getOperand(0);
+  SDOperand    R0 = DAG.getRegister(ARM::R0, MVT::i32);
+  SDOperand    R1 = DAG.getRegister(ARM::R1, MVT::i32);
+
   switch(Op.getNumOperands()) {
   default:
     assert(0 && "Do not know how to return this many arguments!");
@@ -248,13 +257,24 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
   case 3: {
     SDOperand Val = Op.getOperand(1);
     assert(Val.getValueType() == MVT::i32 ||
-          Val.getValueType() == MVT::f32);
+          Val.getValueType() == MVT::f32 ||
+          Val.getValueType() == MVT::f64);
+
+    if (Val.getValueType() == MVT::f64) {
+      SDVTList    VTs = DAG.getVTList(MVT::Other, MVT::Flag);
+      SDOperand Ops[] = {Chain, R0, R1, Val};
+      Copy  = DAG.getNode(ARMISD::FMRRD, VTs, Ops, 4);
+    } else {
+      if (Val.getValueType() == MVT::f32)
+       Val = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Val);
+      Copy = DAG.getCopyToReg(Chain, R0, Val, SDOperand());
+    }
 
-    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())
+    if (DAG.getMachineFunction().liveout_empty()) {
       DAG.getMachineFunction().addLiveOut(ARM::R0);
+      if (Val.getValueType() == MVT::f64)
+        DAG.getMachineFunction().addLiveOut(ARM::R1);
+    }
     break;
   }
   case 5:
@@ -421,12 +441,15 @@ static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) {
 }
 
 static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand IntVal = Op.getOperand(0);
+  SDOperand IntVal  = Op.getOperand(0);
   assert(IntVal.getValueType() == MVT::i32);
-  assert(Op.getValueType()     == MVT::f32);
+  MVT::ValueType vt = Op.getValueType();
+  assert(vt == MVT::f32 ||
+         vt == MVT::f64);
 
   SDOperand Tmp = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, IntVal);
-  return  DAG.getNode(ARMISD::FSITOS, MVT::f32, Tmp);
+  ARMISD::NodeType op = vt == MVT::f32 ? ARMISD::FSITOS : ARMISD::FSITOD;
+  return DAG.getNode(op, vt, Tmp);
 }
 
 SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
index 0253947c4cf86cbc2ae6abf391fbe238bf438660..d7c096f37b251eebd2a9aaac7d9c7a4de2632fc5 100644 (file)
@@ -75,6 +75,10 @@ def SDTVoidBinOp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
 def armcmp       : SDNode<"ARMISD::CMP",  SDTVoidBinOp, [SDNPOutFlag]>;
 
 def armfsitos    : SDNode<"ARMISD::FSITOS", SDTUnaryOp>;
+def armfsitod      : SDNode<"ARMISD::FSITOD", SDTUnaryOp>;
+
+def SDTarmfmrrd    : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>, SDTCisFP<2>]>;
+def armfmrrd       : SDNode<"ARMISD::FMRRD", SDTarmfmrrd, [SDNPHasChain, SDNPOutFlag]>;
 
 def ADJCALLSTACKUP : InstARM<(ops i32imm:$amt),
                             "!ADJCALLSTACKUP $amt",
@@ -164,5 +168,11 @@ def FMSR    : InstARM<(ops FPRegs:$dst, IntRegs:$src),
 def FMRS    : InstARM<(ops IntRegs:$dst, FPRegs:$src),
                        "fmrs $dst, $src", [(set IntRegs:$dst, (bitconvert FPRegs:$src))]>;
 
+def FMRRD   : InstARM<(ops IntRegs:$i0, IntRegs:$i1, DFPRegs:$src),
+                       "fmrrd $i0, $i1, $src", [(armfmrrd IntRegs:$i0, IntRegs:$i1, DFPRegs:$src)]>;
+
 def FSITOS  : InstARM<(ops FPRegs:$dst, FPRegs:$src),
                        "fsitos $dst, $src", [(set FPRegs:$dst, (armfsitos FPRegs:$src))]>;
+
+def FSITOD  : InstARM<(ops DFPRegs:$dst, FPRegs:$src),
+                       "fsitod $dst, $src", [(set DFPRegs:$dst, (armfsitod FPRegs:$src))]>;
index 143b953508bee8ec6df3219b3d958456f6431b93..ca57598cc9ed96a96bdcf8e65331620075ffad04 100644 (file)
@@ -88,22 +88,22 @@ 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>;
+def D0  : Rd< 0,  "D0", [S0,   S1]>, DwarfRegNum<64>;
+def D1  : Rd< 2,  "D1", [S2,   S3]>, DwarfRegNum<66>;
+def D2  : Rd< 4,  "D2", [S4,   S5]>, DwarfRegNum<68>;
+def D3  : Rd< 6,  "D3", [S6,   S7]>, DwarfRegNum<70>;
+def D4  : Rd< 8,  "D4", [S8,   S9]>, DwarfRegNum<72>;
+def D5  : Rd<10,  "D5", [S10, S11]>, DwarfRegNum<74>;
+def D6  : Rd<12,  "D6", [S12, S13]>, DwarfRegNum<76>;
+def D7  : Rd<14,  "D7", [S14, S15]>, DwarfRegNum<78>;
+def D8  : Rd<16,  "D8", [S16, S17]>, DwarfRegNum<80>;
+def D9  : Rd<18,  "D9", [S18, S19]>, DwarfRegNum<82>;
+def D10 : Rd<20, "D10", [S20, S21]>, DwarfRegNum<84>;
+def D11 : Rd<22, "D11", [S22, S23]>, DwarfRegNum<86>;
+def D12 : Rd<24, "D12", [S24, S25]>, DwarfRegNum<88>;
+def D13 : Rd<26, "D13", [S26, S27]>, DwarfRegNum<90>;
+def D14 : Rd<28, "D14", [S28, S29]>, DwarfRegNum<92>;
+def D15 : Rd<30, "D15", [S30, S31]>, DwarfRegNum<94>;
 
 // Register classes.
 //
index 60e96f0414e9bf7bd70c391e92ee8a909dc52ad1..af5a69642c4490e4a985cc8b1519386c1acf0d46 100644 (file)
@@ -1,10 +1,18 @@
 ; RUN: llvm-as < %s | llc -march=arm &&
-; RUN: llvm-as < %s | llc -march=arm | grep fmsr &&
+; RUN: llvm-as < %s | llc -march=arm | grep fmsr | wc -l | grep 2 &&
 ; RUN: llvm-as < %s | llc -march=arm | grep fsitos &&
-; RUN: llvm-as < %s | llc -march=arm | grep fmrs
+; RUN: llvm-as < %s | llc -march=arm | grep fmrs &&
+; RUN: llvm-as < %s | llc -march=arm | grep fsitod &&
+; RUN: llvm-as < %s | llc -march=arm | grep fmrrd
 
 float %f(int %a) {
 entry:
        %tmp = cast int %a to float             ; <float> [#uses=1]
        ret float %tmp
 }
+
+double %g(int %a) {
+entry:
+        %tmp = cast int %a to double            ; <double> [#uses=1]
+        ret double %tmp
+}