aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/SystemZ
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-10-01 13:18:56 +0000
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-10-01 13:18:56 +0000
commit645d250b84fe0d097e7813b980ae58daeca2c2e6 (patch)
tree546e722390d56140fee454cc642a0d234d85291c /lib/Target/SystemZ
parent2e1625475fab156b98204fa73c168ca4a828b775 (diff)
downloadexternal_llvm-645d250b84fe0d097e7813b980ae58daeca2c2e6.zip
external_llvm-645d250b84fe0d097e7813b980ae58daeca2c2e6.tar.gz
external_llvm-645d250b84fe0d097e7813b980ae58daeca2c2e6.tar.bz2
[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
Diffstat (limited to 'lib/Target/SystemZ')
-rw-r--r--lib/Target/SystemZ/SystemZAsmPrinter.cpp17
-rw-r--r--lib/Target/SystemZ/SystemZInstrFormats.td8
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.cpp8
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.td12
4 files changed, 43 insertions, 2 deletions
diff --git a/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 0a89a96..cb01949 100644
--- a/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -36,6 +36,15 @@ static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
}
// 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
// R2 register turned into a GR64.
static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
return MCInstBuilder(Opcode)
@@ -113,6 +122,14 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
#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:
Lower.lower(MI, LoweredMI);
break;
diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td
index c74091f..aa15ebd 100644
--- a/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -1378,6 +1378,14 @@ class UnaryRRPseudo<string key, SDPatternOperator operator,
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.
class StoreRXYPseudo<SDPatternOperator operator, RegisterOperand cls,
bits<5> bytes, AddressingMode mode = bdxaddr20only>
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 3abecf6..90de3da 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -881,6 +881,14 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
expandRIPseudo(MI, SystemZ::IILF, SystemZ::IIHF, false);
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:
splitAdjDynAlloc(MI);
return true;
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td
index ac1ca3c..e19cc27 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -629,12 +629,20 @@ defm : InsertMem<"inserti8", ICY, GR64, azextloadi8, bdxaddr20pair>;
// Insertions of a 16-bit immediate, leaving other bits unaffected.
// We don't have or_as_insert equivalents of these operations because
// 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 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 IILH64 : BinaryAliasRI<insertlh, GR64, imm64lh16>;
-def IIHL : BinaryRI<"iihl", 0xA51, inserthl, GR64, imm64hl16>;
-def IIHH : BinaryRI<"iihh", 0xA50, inserthh, GR64, imm64hh16>;
+def IIHL64 : BinaryAliasRI<inserthl, GR64, imm64hl16>;
+def IIHH64 : BinaryAliasRI<inserthh, GR64, imm64hh16>;
// ...likewise for 32-bit immediates. For GR32s this is a general
// full-width move. (We use IILF rather than something like LLILF