mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
Materialize 64-bit immediates.
The last resort pattern produces 6 instructions, and there are still opportunities for materializing some immediates in fewer instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178526 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c3ff3f42ee
commit
39e75544dc
@ -45,3 +45,91 @@ defm SRLX : F3_S<"srlx", 0b100110, 1, srl, i64, I64Regs>;
|
||||
defm SRAX : F3_S<"srax", 0b100111, 1, sra, i64, I64Regs>;
|
||||
|
||||
} // Predicates = [Is64Bit]
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 64-bit Immediates.
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// All 32-bit immediates can be materialized with sethi+or, but 64-bit
|
||||
// immediates may require more code. There may be a point where it is
|
||||
// preferable to use a constant pool load instead, depending on the
|
||||
// microarchitecture.
|
||||
|
||||
// The %g0 register is constant 0.
|
||||
// This is useful for stx %g0, [...], for example.
|
||||
def : Pat<(i64 0), (i64 G0)>, Requires<[Is64Bit]>;
|
||||
|
||||
// Single-instruction patterns.
|
||||
|
||||
// The ALU instructions want their simm13 operands as i32 immediates.
|
||||
def as_i32imm : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
|
||||
}]>;
|
||||
def : Pat<(i64 simm13:$val), (ORri (i64 G0), (as_i32imm $val))>;
|
||||
def : Pat<(i64 SETHIimm:$val), (SETHIi (HI22 $val))>;
|
||||
|
||||
// Double-instruction patterns.
|
||||
|
||||
// All unsigned i32 immediates can be handled by sethi+or.
|
||||
def uimm32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
|
||||
def : Pat<(i64 uimm32:$val), (ORri (SETHIi (HI22 $val)), (LO10 $val))>,
|
||||
Requires<[Is64Bit]>;
|
||||
|
||||
// All negative i33 immediates can be handled by sethi+xor.
|
||||
def nimm33 : PatLeaf<(imm), [{
|
||||
int64_t Imm = N->getSExtValue();
|
||||
return Imm < 0 && isInt<33>(Imm);
|
||||
}]>;
|
||||
// Bits 10-31 inverted. Same as assembler's %hix.
|
||||
def HIX22 : SDNodeXForm<imm, [{
|
||||
uint64_t Val = (~N->getZExtValue() >> 10) & ((1u << 22) - 1);
|
||||
return CurDAG->getTargetConstant(Val, MVT::i32);
|
||||
}]>;
|
||||
// Bits 0-9 with ones in bits 10-31. Same as assembler's %lox.
|
||||
def LOX10 : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(~(~N->getZExtValue() & 0x3ff), MVT::i32);
|
||||
}]>;
|
||||
def : Pat<(i64 nimm33:$val), (XORri (SETHIi (HIX22 $val)), (LOX10 $val))>,
|
||||
Requires<[Is64Bit]>;
|
||||
|
||||
// More possible patterns:
|
||||
//
|
||||
// (sllx sethi, n)
|
||||
// (sllx simm13, n)
|
||||
//
|
||||
// 3 instrs:
|
||||
//
|
||||
// (xor (sllx sethi), simm13)
|
||||
// (sllx (xor sethi, simm13))
|
||||
//
|
||||
// 4 instrs:
|
||||
//
|
||||
// (or sethi, (sllx sethi))
|
||||
// (xnor sethi, (sllx sethi))
|
||||
//
|
||||
// 5 instrs:
|
||||
//
|
||||
// (or (sllx sethi), (or sethi, simm13))
|
||||
// (xnor (sllx sethi), (or sethi, simm13))
|
||||
// (or (sllx sethi), (sllx sethi))
|
||||
// (xnor (sllx sethi), (sllx sethi))
|
||||
//
|
||||
// Worst case is 6 instrs:
|
||||
//
|
||||
// (or (sllx (or sethi, simmm13)), (or sethi, simm13))
|
||||
|
||||
// Bits 42-63, same as assembler's %hh.
|
||||
def HH22 : SDNodeXForm<imm, [{
|
||||
uint64_t Val = (N->getZExtValue() >> 42) & ((1u << 22) - 1);
|
||||
return CurDAG->getTargetConstant(Val, MVT::i32);
|
||||
}]>;
|
||||
// Bits 32-41, same as assembler's %hm.
|
||||
def HM10 : SDNodeXForm<imm, [{
|
||||
uint64_t Val = (N->getZExtValue() >> 32) & ((1u << 10) - 1);
|
||||
return CurDAG->getTargetConstant(Val, MVT::i32);
|
||||
}]>;
|
||||
def : Pat<(i64 imm:$val),
|
||||
(ORrr (SLLXri (ORri (SETHIi (HH22 $val)), (HM10 $val)), (i64 32)),
|
||||
(ORri (SETHIi (HI22 $val)), (LO10 $val)))>,
|
||||
Requires<[Is64Bit]>;
|
||||
|
@ -19,3 +19,49 @@ define i64 @sra_reg(i64 %a, i64 %b) {
|
||||
%x = ashr i64 %a, %b
|
||||
ret i64 %x
|
||||
}
|
||||
|
||||
; Immediate materialization. Many of these patterns could actually be merged
|
||||
; into the restore instruction:
|
||||
;
|
||||
; restore %g0, %g0, %o0
|
||||
;
|
||||
; CHECK: ret_imm0
|
||||
; CHECK: or %g0, %g0, %i0
|
||||
define i64 @ret_imm0() {
|
||||
ret i64 0
|
||||
}
|
||||
|
||||
; CHECK: ret_simm13
|
||||
; CHECK: or %g0, -4096, %i0
|
||||
define i64 @ret_simm13() {
|
||||
ret i64 -4096
|
||||
}
|
||||
|
||||
; CHECK: ret_sethi
|
||||
; CHECK: sethi 4, %i0
|
||||
; CHECK-NOT: or
|
||||
; CHECK: restore
|
||||
define i64 @ret_sethi() {
|
||||
ret i64 4096
|
||||
}
|
||||
|
||||
; CHECK: ret_sethi
|
||||
; CHECK: sethi 4, [[R:%[goli][0-7]]]
|
||||
; CHECK: or [[R]], 1, %i0
|
||||
define i64 @ret_sethi_or() {
|
||||
ret i64 4097
|
||||
}
|
||||
|
||||
; CHECK: ret_nimm33
|
||||
; CHECK: sethi 4, [[R:%[goli][0-7]]]
|
||||
; CHECK: xor [[R]], -4, %i0
|
||||
define i64 @ret_nimm33() {
|
||||
ret i64 -4100
|
||||
}
|
||||
|
||||
; CHECK: ret_bigimm
|
||||
; CHECK: sethi
|
||||
; CHECK: sethi
|
||||
define i64 @ret_bigimm() {
|
||||
ret i64 6800754272627607872
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user