mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-27 12:26:08 +00:00
[SystemZ] Allow integer insertions with a high-word destination
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191753 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -35,6 +35,15 @@ static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
|
|||||||
.addImm(MI->getOperand(2).getImm());
|
.addImm(MI->getOperand(2).getImm());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return an RI instruction like MI with opcode Opcode, but with the
|
||||||
|
// GR64 register operands turned into GRH32s.
|
||||||
|
static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
|
||||||
|
return MCInstBuilder(Opcode)
|
||||||
|
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
|
||||||
|
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
|
||||||
|
.addImm(MI->getOperand(2).getImm());
|
||||||
|
}
|
||||||
|
|
||||||
// Return an RI instruction like MI with opcode Opcode, but with the
|
// Return an RI instruction like MI with opcode Opcode, but with the
|
||||||
// R2 register turned into a GR64.
|
// R2 register turned into a GR64.
|
||||||
static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
|
static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
|
||||||
@@ -113,6 +122,14 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
|
|
||||||
#undef LOWER_LOW
|
#undef LOWER_LOW
|
||||||
|
|
||||||
|
#define LOWER_HIGH(NAME) \
|
||||||
|
case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
|
||||||
|
|
||||||
|
LOWER_HIGH(IIHL);
|
||||||
|
LOWER_HIGH(IIHH);
|
||||||
|
|
||||||
|
#undef LOWER_HIGH
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Lower.lower(MI, LoweredMI);
|
Lower.lower(MI, LoweredMI);
|
||||||
break;
|
break;
|
||||||
|
@@ -1378,6 +1378,14 @@ class UnaryRRPseudo<string key, SDPatternOperator operator,
|
|||||||
let OpType = "reg";
|
let OpType = "reg";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Like BinaryRI, but expanded after RA depending on the choice of register.
|
||||||
|
class BinaryRIPseudo<SDPatternOperator operator, RegisterOperand cls,
|
||||||
|
Immediate imm>
|
||||||
|
: Pseudo<(outs cls:$R1), (ins cls:$R1src, imm:$I2),
|
||||||
|
[(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
|
||||||
|
let Constraints = "$R1 = $R1src";
|
||||||
|
}
|
||||||
|
|
||||||
// Like StoreRXY, but expanded after RA depending on the choice of registers.
|
// Like StoreRXY, but expanded after RA depending on the choice of registers.
|
||||||
class StoreRXYPseudo<SDPatternOperator operator, RegisterOperand cls,
|
class StoreRXYPseudo<SDPatternOperator operator, RegisterOperand cls,
|
||||||
bits<5> bytes, AddressingMode mode = bdxaddr20only>
|
bits<5> bytes, AddressingMode mode = bdxaddr20only>
|
||||||
|
@@ -881,6 +881,14 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
|
|||||||
expandRIPseudo(MI, SystemZ::IILF, SystemZ::IIHF, false);
|
expandRIPseudo(MI, SystemZ::IILF, SystemZ::IIHF, false);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case SystemZ::IILMux:
|
||||||
|
expandRIPseudo(MI, SystemZ::IILL, SystemZ::IIHL, false);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case SystemZ::IIHMux:
|
||||||
|
expandRIPseudo(MI, SystemZ::IILH, SystemZ::IIHH, false);
|
||||||
|
return true;
|
||||||
|
|
||||||
case SystemZ::ADJDYNALLOC:
|
case SystemZ::ADJDYNALLOC:
|
||||||
splitAdjDynAlloc(MI);
|
splitAdjDynAlloc(MI);
|
||||||
return true;
|
return true;
|
||||||
|
@@ -629,12 +629,20 @@ defm : InsertMem<"inserti8", ICY, GR64, azextloadi8, bdxaddr20pair>;
|
|||||||
// Insertions of a 16-bit immediate, leaving other bits unaffected.
|
// Insertions of a 16-bit immediate, leaving other bits unaffected.
|
||||||
// We don't have or_as_insert equivalents of these operations because
|
// We don't have or_as_insert equivalents of these operations because
|
||||||
// OI is available instead.
|
// OI is available instead.
|
||||||
|
//
|
||||||
|
// IIxMux expands to II[LH]x, depending on the choice of register.
|
||||||
|
def IILMux : BinaryRIPseudo<insertll, GRX32, imm32ll16>,
|
||||||
|
Requires<[FeatureHighWord]>;
|
||||||
|
def IIHMux : BinaryRIPseudo<insertlh, GRX32, imm32lh16>,
|
||||||
|
Requires<[FeatureHighWord]>;
|
||||||
def IILL : BinaryRI<"iill", 0xA53, insertll, GR32, imm32ll16>;
|
def IILL : BinaryRI<"iill", 0xA53, insertll, GR32, imm32ll16>;
|
||||||
def IILH : BinaryRI<"iilh", 0xA52, insertlh, GR32, imm32lh16>;
|
def IILH : BinaryRI<"iilh", 0xA52, insertlh, GR32, imm32lh16>;
|
||||||
|
def IIHL : BinaryRI<"iihl", 0xA51, insertll, GRH32, imm32ll16>;
|
||||||
|
def IIHH : BinaryRI<"iihh", 0xA50, insertlh, GRH32, imm32lh16>;
|
||||||
def IILL64 : BinaryAliasRI<insertll, GR64, imm64ll16>;
|
def IILL64 : BinaryAliasRI<insertll, GR64, imm64ll16>;
|
||||||
def IILH64 : BinaryAliasRI<insertlh, GR64, imm64lh16>;
|
def IILH64 : BinaryAliasRI<insertlh, GR64, imm64lh16>;
|
||||||
def IIHL : BinaryRI<"iihl", 0xA51, inserthl, GR64, imm64hl16>;
|
def IIHL64 : BinaryAliasRI<inserthl, GR64, imm64hl16>;
|
||||||
def IIHH : BinaryRI<"iihh", 0xA50, inserthh, GR64, imm64hh16>;
|
def IIHH64 : BinaryAliasRI<inserthh, GR64, imm64hh16>;
|
||||||
|
|
||||||
// ...likewise for 32-bit immediates. For GR32s this is a general
|
// ...likewise for 32-bit immediates. For GR32s this is a general
|
||||||
// full-width move. (We use IILF rather than something like LLILF
|
// full-width move. (We use IILF rather than something like LLILF
|
||||||
|
@@ -315,3 +315,41 @@ define void @f14(i32 %x, i32 %y) {
|
|||||||
call void asm sideeffect "blah $0", "r"(i32 %val)
|
call void asm sideeffect "blah $0", "r"(i32 %val)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Test immediate insertion involving high registers.
|
||||||
|
define void @f15() {
|
||||||
|
; CHECK-LABEL: f15:
|
||||||
|
; CHECK: stepa [[REG:%r[0-5]]]
|
||||||
|
; CHECK: iihh [[REG]], 4660
|
||||||
|
; CHECK: stepb [[REG]]
|
||||||
|
; CHECK: iihl [[REG]], 34661
|
||||||
|
; CHECK: stepc [[REG]]
|
||||||
|
; CHECK: br %r14
|
||||||
|
%res1 = call i32 asm "stepa $0", "=h"()
|
||||||
|
%and1 = and i32 %res1, 65535
|
||||||
|
%or1 = or i32 %and1, 305397760
|
||||||
|
%res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1)
|
||||||
|
%and2 = and i32 %res2, -65536
|
||||||
|
%or2 = or i32 %and2, 34661
|
||||||
|
call void asm sideeffect "stepc $0", "h"(i32 %or2)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Test immediate insertion involving low registers.
|
||||||
|
define void @f16() {
|
||||||
|
; CHECK-LABEL: f16:
|
||||||
|
; CHECK: stepa [[REG:%r[0-5]]]
|
||||||
|
; CHECK: iilh [[REG]], 4660
|
||||||
|
; CHECK: stepb [[REG]]
|
||||||
|
; CHECK: iill [[REG]], 34661
|
||||||
|
; CHECK: stepc [[REG]]
|
||||||
|
; CHECK: br %r14
|
||||||
|
%res1 = call i32 asm "stepa $0", "=r"()
|
||||||
|
%and1 = and i32 %res1, 65535
|
||||||
|
%or1 = or i32 %and1, 305397760
|
||||||
|
%res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1)
|
||||||
|
%and2 = and i32 %res2, -65536
|
||||||
|
%or2 = or i32 %and2, 34661
|
||||||
|
call void asm sideeffect "stepc $0", "r"(i32 %or2)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user