mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
Two improvements:
1. Codegen this comparison: if (X == 0x8000) as: cmplwi cr0, r3, 32768 bne cr0, LBB1_2 ;cond_next instead of: lis r2, 0 ori r2, r2, 32768 cmpw cr0, r3, r2 bne cr0, LBB1_2 ;cond_next 2. Codegen this comparison: if (X == 0x12345678) as: xoris r2, r3, 4660 cmplwi cr0, r2, 22136 bne cr0, LBB1_2 ;cond_next instead of: lis r2, 4660 ori r2, r2, 22136 cmpw cr0, r3, r2 bne cr0, LBB1_2 ;cond_next git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30509 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cc96ac3a7d
commit
3836dbd3bd
@ -699,7 +699,33 @@ SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
|
||||
|
||||
if (LHS.getValueType() == MVT::i32) {
|
||||
unsigned Imm;
|
||||
if (ISD::isUnsignedIntSetCC(CC)) {
|
||||
if (CC == ISD::SETEQ || CC == ISD::SETNE) {
|
||||
if (isInt32Immediate(RHS, Imm)) {
|
||||
// SETEQ/SETNE comparison with 16-bit immediate, fold it.
|
||||
if (isUInt16(Imm))
|
||||
return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, LHS,
|
||||
getI32Imm(Imm & 0xFFFF)), 0);
|
||||
// If this is a 16-bit signed immediate, fold it.
|
||||
if (isInt16(Imm))
|
||||
return SDOperand(CurDAG->getTargetNode(PPC::CMPWI, MVT::i32, LHS,
|
||||
getI32Imm(Imm & 0xFFFF)), 0);
|
||||
|
||||
// For non-equality comparisons, the default code would materialize the
|
||||
// constant, then compare against it, like this:
|
||||
// lis r2, 4660
|
||||
// ori r2, r2, 22136
|
||||
// cmpw cr0, r3, r2
|
||||
// Since we are just comparing for equality, we can emit this instead:
|
||||
// xoris r0,r3,0x1234
|
||||
// cmplwi cr0,r0,0x5678
|
||||
// beq cr0,L6
|
||||
SDOperand Xor(CurDAG->getTargetNode(PPC::XORIS, MVT::i32, LHS,
|
||||
getI32Imm(Imm >> 16)), 0);
|
||||
return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, Xor,
|
||||
getI32Imm(Imm & 0xFFFF)), 0);
|
||||
}
|
||||
Opc = PPC::CMPLW;
|
||||
} else if (ISD::isUnsignedIntSetCC(CC)) {
|
||||
if (isInt32Immediate(RHS, Imm) && isUInt16(Imm))
|
||||
return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, LHS,
|
||||
getI32Imm(Imm & 0xFFFF)), 0);
|
||||
|
@ -50,27 +50,6 @@ we don't have to always run the branch selector for small functions.
|
||||
|
||||
===-------------------------------------------------------------------------===
|
||||
|
||||
* Codegen this:
|
||||
|
||||
void test2(int X) {
|
||||
if (X == 0x12345678) bar();
|
||||
}
|
||||
|
||||
as:
|
||||
|
||||
xoris r0,r3,0x1234
|
||||
cmplwi cr0,r0,0x5678
|
||||
beq cr0,L6
|
||||
|
||||
not:
|
||||
|
||||
lis r2, 4660
|
||||
ori r2, r2, 22136
|
||||
cmpw cr0, r3, r2
|
||||
bne .LBB_test2_2
|
||||
|
||||
===-------------------------------------------------------------------------===
|
||||
|
||||
Lump the constant pool for each function into ONE pic object, and reference
|
||||
pieces of it as offsets from the start. For functions like this (contrived
|
||||
to have lots of constants obviously):
|
||||
|
Loading…
Reference in New Issue
Block a user