mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-01 15:17:25 +00:00
R600/SI: Handle i64 sub.
We can handle it the same way as add git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211514 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -85,7 +85,7 @@ private:
|
||||
bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset);
|
||||
bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset);
|
||||
|
||||
SDNode *SelectADD_I64(SDNode *N);
|
||||
SDNode *SelectADD_SUB_I64(SDNode *N);
|
||||
|
||||
// Include the pieces autogenerated from the target description.
|
||||
#include "AMDGPUGenDAGISel.inc"
|
||||
@@ -214,12 +214,13 @@ SDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) {
|
||||
// We are selecting i64 ADD here instead of custom lower it during
|
||||
// DAG legalization, so we can fold some i64 ADDs used for address
|
||||
// calculation into the LOAD and STORE instructions.
|
||||
case ISD::ADD: {
|
||||
case ISD::ADD:
|
||||
case ISD::SUB: {
|
||||
if (N->getValueType(0) != MVT::i64 ||
|
||||
ST.getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS)
|
||||
break;
|
||||
|
||||
return SelectADD_I64(N);
|
||||
return SelectADD_SUB_I64(N);
|
||||
}
|
||||
case ISD::SCALAR_TO_VECTOR:
|
||||
case AMDGPUISD::BUILD_VERTICAL_VECTOR:
|
||||
@@ -646,11 +647,13 @@ bool AMDGPUDAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base,
|
||||
return true;
|
||||
}
|
||||
|
||||
SDNode *AMDGPUDAGToDAGISel::SelectADD_I64(SDNode *N) {
|
||||
SDNode *AMDGPUDAGToDAGISel::SelectADD_SUB_I64(SDNode *N) {
|
||||
SDLoc DL(N);
|
||||
SDValue LHS = N->getOperand(0);
|
||||
SDValue RHS = N->getOperand(1);
|
||||
|
||||
bool IsAdd = (N->getOpcode() == ISD::ADD);
|
||||
|
||||
SDValue Sub0 = CurDAG->getTargetConstant(AMDGPU::sub0, MVT::i32);
|
||||
SDValue Sub1 = CurDAG->getTargetConstant(AMDGPU::sub1, MVT::i32);
|
||||
|
||||
@@ -665,16 +668,22 @@ SDNode *AMDGPUDAGToDAGISel::SelectADD_I64(SDNode *N) {
|
||||
DL, MVT::i32, RHS, Sub1);
|
||||
|
||||
SDVTList VTList = CurDAG->getVTList(MVT::i32, MVT::Glue);
|
||||
|
||||
SDValue AddLoArgs[] = { SDValue(Lo0, 0), SDValue(Lo1, 0) };
|
||||
|
||||
SDNode *AddLo = CurDAG->getMachineNode(
|
||||
isCFDepth0() ? AMDGPU::S_ADD_I32 : AMDGPU::V_ADD_I32_e32,
|
||||
DL, VTList, AddLoArgs);
|
||||
SDValue Carry = SDValue(AddLo, 1);
|
||||
SDNode *AddHi = CurDAG->getMachineNode(
|
||||
isCFDepth0() ? AMDGPU::S_ADDC_U32 : AMDGPU::V_ADDC_U32_e32,
|
||||
DL, MVT::i32, SDValue(Hi0, 0), SDValue(Hi1, 0), Carry);
|
||||
|
||||
unsigned Opc = IsAdd ? AMDGPU::S_ADD_I32 : AMDGPU::S_SUB_I32;
|
||||
unsigned CarryOpc = IsAdd ? AMDGPU::S_ADDC_U32 : AMDGPU::S_SUBB_U32;
|
||||
|
||||
if (!isCFDepth0()) {
|
||||
Opc = IsAdd ? AMDGPU::V_ADD_I32_e32 : AMDGPU::V_SUB_I32_e32;
|
||||
CarryOpc = IsAdd ? AMDGPU::V_ADDC_U32_e32 : AMDGPU::V_SUBB_U32_e32;
|
||||
}
|
||||
|
||||
SDNode *AddLo = CurDAG->getMachineNode( Opc, DL, VTList, AddLoArgs);
|
||||
SDValue Carry(AddLo, 1);
|
||||
SDNode *AddHi
|
||||
= CurDAG->getMachineNode(CarryOpc, DL, MVT::i32,
|
||||
SDValue(Hi0, 0), SDValue(Hi1, 0), Carry);
|
||||
|
||||
SDValue Args[5] = {
|
||||
CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, MVT::i32),
|
||||
|
||||
Reference in New Issue
Block a user