mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 21:29:41 +00:00
fix ldu/stu jit encoding. Swith 64-bit preinc load instrs to use memri
addrmodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31757 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
214ca23aef
commit
0851b4f3ed
@ -828,36 +828,37 @@ SDNode *PPCDAGToDAGISel::Select(SDOperand Op) {
|
|||||||
if (LD->getAddressingMode() != ISD::PRE_INC)
|
if (LD->getAddressingMode() != ISD::PRE_INC)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
unsigned Opcode;
|
|
||||||
bool isSExt = LD->getExtensionType() == ISD::SEXTLOAD;
|
|
||||||
if (LD->getValueType(0) != MVT::i64) {
|
|
||||||
// Handle PPC32 integer and normal FP loads.
|
|
||||||
assert(!isSExt || LoadedVT == MVT::i16 && "Invalid sext update load");
|
|
||||||
switch (LoadedVT) {
|
|
||||||
default: assert(0 && "Invalid PPC load type!");
|
|
||||||
case MVT::f64: Opcode = PPC::LFDU; break;
|
|
||||||
case MVT::f32: Opcode = PPC::LFSU; break;
|
|
||||||
case MVT::i32: Opcode = PPC::LWZU; break;
|
|
||||||
case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU; break;
|
|
||||||
case MVT::i1:
|
|
||||||
case MVT::i8: Opcode = PPC::LBZU; break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assert(LD->getValueType(0) == MVT::i64 && "Unknown load result type!");
|
|
||||||
assert(!isSExt || LoadedVT == MVT::i16 && "Invalid sext update load");
|
|
||||||
switch (LoadedVT) {
|
|
||||||
default: assert(0 && "Invalid PPC load type!");
|
|
||||||
case MVT::i64: Opcode = PPC::LDU; break;
|
|
||||||
case MVT::i32: Opcode = PPC::LWZU8; break;
|
|
||||||
case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8; break;
|
|
||||||
case MVT::i1:
|
|
||||||
case MVT::i8: Opcode = PPC::LBZU8; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDOperand Offset = LD->getOffset();
|
SDOperand Offset = LD->getOffset();
|
||||||
if (isa<ConstantSDNode>(Offset) ||
|
if (isa<ConstantSDNode>(Offset) ||
|
||||||
Offset.getOpcode() == ISD::TargetGlobalAddress) {
|
Offset.getOpcode() == ISD::TargetGlobalAddress) {
|
||||||
|
|
||||||
|
unsigned Opcode;
|
||||||
|
bool isSExt = LD->getExtensionType() == ISD::SEXTLOAD;
|
||||||
|
if (LD->getValueType(0) != MVT::i64) {
|
||||||
|
// Handle PPC32 integer and normal FP loads.
|
||||||
|
assert(!isSExt || LoadedVT == MVT::i16 && "Invalid sext update load");
|
||||||
|
switch (LoadedVT) {
|
||||||
|
default: assert(0 && "Invalid PPC load type!");
|
||||||
|
case MVT::f64: Opcode = PPC::LFDU; break;
|
||||||
|
case MVT::f32: Opcode = PPC::LFSU; break;
|
||||||
|
case MVT::i32: Opcode = PPC::LWZU; break;
|
||||||
|
case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU; break;
|
||||||
|
case MVT::i1:
|
||||||
|
case MVT::i8: Opcode = PPC::LBZU; break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(LD->getValueType(0) == MVT::i64 && "Unknown load result type!");
|
||||||
|
assert(!isSExt || LoadedVT == MVT::i16 && "Invalid sext update load");
|
||||||
|
switch (LoadedVT) {
|
||||||
|
default: assert(0 && "Invalid PPC load type!");
|
||||||
|
case MVT::i64: Opcode = PPC::LDU; break;
|
||||||
|
case MVT::i32: Opcode = PPC::LWZU8; break;
|
||||||
|
case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8; break;
|
||||||
|
case MVT::i1:
|
||||||
|
case MVT::i8: Opcode = PPC::LBZU8; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDOperand Chain = LD->getChain();
|
SDOperand Chain = LD->getChain();
|
||||||
SDOperand Base = LD->getBasePtr();
|
SDOperand Base = LD->getBasePtr();
|
||||||
AddToISelQueue(Chain);
|
AddToISelQueue(Chain);
|
||||||
|
@ -877,12 +877,12 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
|
|||||||
MVT::ValueType VT;
|
MVT::ValueType VT;
|
||||||
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
||||||
Ptr = LD->getBasePtr();
|
Ptr = LD->getBasePtr();
|
||||||
VT = LD->getValueType(0);
|
VT = LD->getLoadedVT();
|
||||||
|
|
||||||
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
|
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
|
||||||
ST = ST;
|
ST = ST;
|
||||||
Ptr = ST->getBasePtr();
|
Ptr = ST->getBasePtr();
|
||||||
VT = ST->getStoredVT();
|
VT = ST->getStoredVT();
|
||||||
return false; // TODO: Stores.
|
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -890,18 +890,27 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
|
|||||||
if (MVT::isVector(VT))
|
if (MVT::isVector(VT))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO: Handle reg+reg.
|
// TODO: Check reg+reg first.
|
||||||
if (!SelectAddressRegImm(Ptr, Offset, Base, DAG))
|
|
||||||
return false;
|
// LDU/STU use reg+imm*4, others use reg+imm.
|
||||||
|
if (VT != MVT::i64) {
|
||||||
|
// reg + imm
|
||||||
|
if (!SelectAddressRegImm(Ptr, Offset, Base, DAG))
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// reg + imm * 4.
|
||||||
|
if (!SelectAddressRegImmShift(Ptr, Offset, Base, DAG))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// PPC64 doesn't have lwau, but it does have lwaux. Reject preinc load of
|
|
||||||
// sext i32 to i64 when addr mode is r+i.
|
|
||||||
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
||||||
|
// PPC64 doesn't have lwau, but it does have lwaux. Reject preinc load of
|
||||||
|
// sext i32 to i64 when addr mode is r+i.
|
||||||
if (LD->getValueType(0) == MVT::i64 && LD->getLoadedVT() == MVT::i32 &&
|
if (LD->getValueType(0) == MVT::i64 && LD->getLoadedVT() == MVT::i32 &&
|
||||||
LD->getExtensionType() == ISD::SEXTLOAD &&
|
LD->getExtensionType() == ISD::SEXTLOAD &&
|
||||||
isa<ConstantSDNode>(Offset))
|
isa<ConstantSDNode>(Offset))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AM = ISD::PRE_INC;
|
AM = ISD::PRE_INC;
|
||||||
return true;
|
return true;
|
||||||
|
@ -322,18 +322,15 @@ def LWZX8 : XForm_1<31, 23, (ops G8RC:$rD, memrr:$src),
|
|||||||
|
|
||||||
|
|
||||||
// Update forms.
|
// Update forms.
|
||||||
def LBZU8 : DForm_1<35, (ops G8RC:$rD, ptr_rc:$rA_result, symbolLo:$disp,
|
def LBZU8 : DForm_1<35, (ops G8RC:$rD, ptr_rc:$ea_result, memri:$addr),
|
||||||
ptr_rc:$rA),
|
"lbzu $rD, $addr", LdStGeneral,
|
||||||
"lbzu $rD, $disp($rA)", LdStGeneral,
|
[]>, RegConstraint<"$addr.reg = $ea_result">;
|
||||||
[]>, RegConstraint<"$rA = $rA_result">;
|
def LHZU8 : DForm_1<41, (ops G8RC:$rD, ptr_rc:$ea_result, memri:$addr),
|
||||||
def LHZU8 : DForm_1<41, (ops G8RC:$rD, ptr_rc:$rA_result, symbolLo:$disp,
|
"lhzu $rD, $addr", LdStGeneral,
|
||||||
ptr_rc:$rA),
|
[]>, RegConstraint<"$addr.reg = $ea_result">;
|
||||||
"lhzu $rD, $disp($rA)", LdStGeneral,
|
def LWZU8 : DForm_1<33, (ops G8RC:$rD, ptr_rc:$ea_result, memri:$addr),
|
||||||
[]>, RegConstraint<"$rA = $rA_result">;
|
"lwzu $rD, $addr", LdStGeneral,
|
||||||
def LWZU8 : DForm_1<33, (ops G8RC:$rD, ptr_rc:$rA_result, symbolLo:$disp,
|
[]>, RegConstraint<"$addr.reg = $ea_result">;
|
||||||
ptr_rc:$rA),
|
|
||||||
"lwzu $rD, $disp($rA)", LdStGeneral,
|
|
||||||
[]>, RegConstraint<"$rA = $rA_result">;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,10 +344,9 @@ def LDX : XForm_1<31, 21, (ops G8RC:$rD, memrr:$src),
|
|||||||
"ldx $rD, $src", LdStLD,
|
"ldx $rD, $src", LdStLD,
|
||||||
[(set G8RC:$rD, (load xaddr:$src))]>, isPPC64;
|
[(set G8RC:$rD, (load xaddr:$src))]>, isPPC64;
|
||||||
|
|
||||||
def LDU : DSForm_1<58, 1, (ops G8RC:$rD, ptr_rc:$rA_result, symbolLo:$disp,
|
def LDU : DSForm_1<58, 1, (ops G8RC:$rD, ptr_rc:$ea_result, memrix:$addr),
|
||||||
ptr_rc:$rA),
|
"ldu $rD, $addr", LdStLD,
|
||||||
"ldu $rD, $disp($rA)", LdStLD,
|
[]>, RegConstraint<"$addr.reg = $ea_result">, isPPC64;
|
||||||
[]>, RegConstraint<"$rA = $rA_result">, isPPC64;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ def memrr : Operand<iPTR> {
|
|||||||
}
|
}
|
||||||
def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits.
|
def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits.
|
||||||
let PrintMethod = "printMemRegImmShifted";
|
let PrintMethod = "printMemRegImmShifted";
|
||||||
let MIOperandInfo = (ops i32imm, ptr_rc);
|
let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PowerPC Predicate operand. 20 = (0<<5)|20 = always, CR0 is a dummy reg
|
// PowerPC Predicate operand. 20 = (0<<5)|20 = always, CR0 is a dummy reg
|
||||||
|
Loading…
x
Reference in New Issue
Block a user