summaryrefslogtreecommitdiff
path: root/lib/Target/SystemZ
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-11-22 17:28:28 +0000
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-11-22 17:28:28 +0000
commitb83bf521136801c1b9ea72dc9daae9428782cc75 (patch)
tree549e24a130f57da2c6d8d0135b6fb507bd34269e /lib/Target/SystemZ
parent4be5f33f6558438e6b104f9c74bf035bb77bdc10 (diff)
downloadllvm-b83bf521136801c1b9ea72dc9daae9428782cc75.tar.gz
llvm-b83bf521136801c1b9ea72dc9daae9428782cc75.tar.bz2
llvm-b83bf521136801c1b9ea72dc9daae9428782cc75.tar.xz
[SystemZ] Fix TMHH and TMHL usage for z10 with -O0
I've no idea why I decided to handle TMxx differently from all the other high/low logic operations, but it was a stupid thing to do. The high registers aren't available as separate 32-bit registers on z10, so subreg_h32 can't be used on a GR64 there. I've normally been testing with z196 and with -O3 and so hadn't noticed this until now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195473 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SystemZ')
-rw-r--r--lib/Target/SystemZ/SystemZAsmPrinter.cpp30
-rw-r--r--lib/Target/SystemZ/SystemZInstrFormats.td7
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.td9
-rw-r--r--lib/Target/SystemZ/SystemZPatterns.td8
4 files changed, 34 insertions, 20 deletions
diff --git a/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 75efdb0941..75cbda4958 100644
--- a/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -29,19 +29,29 @@ using namespace llvm;
// Return an RI instruction like MI with opcode Opcode, but with the
// GR64 register operands turned into GR32s.
static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
- return MCInstBuilder(Opcode)
- .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
- .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
- .addImm(MI->getOperand(2).getImm());
+ if (MI->isCompare())
+ return MCInstBuilder(Opcode)
+ .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
+ .addImm(MI->getOperand(1).getImm());
+ else
+ return MCInstBuilder(Opcode)
+ .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
+ .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
+ .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());
+ if (MI->isCompare())
+ return MCInstBuilder(Opcode)
+ .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
+ .addImm(MI->getOperand(1).getImm());
+ else
+ 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
@@ -112,6 +122,8 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
LOWER_LOW(IILL);
LOWER_LOW(IILH);
+ LOWER_LOW(TMLL);
+ LOWER_LOW(TMLH);
LOWER_LOW(NILL);
LOWER_LOW(NILH);
LOWER_LOW(NILF);
@@ -127,6 +139,8 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
LOWER_HIGH(IIHL);
LOWER_HIGH(IIHH);
+ LOWER_HIGH(TMHL);
+ LOWER_HIGH(TMHH);
LOWER_HIGH(NIHL);
LOWER_HIGH(NIHH);
LOWER_HIGH(NIHF);
diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td
index 353a0d3f73..a8efe165e3 100644
--- a/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -1588,6 +1588,13 @@ class BinaryAliasRIL<SDPatternOperator operator, RegisterOperand cls,
let Constraints = "$R1 = $R1src";
}
+// An alias of a CompareRI, but with different register sizes.
+class CompareAliasRI<SDPatternOperator operator, RegisterOperand cls,
+ Immediate imm>
+ : Alias<4, (outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]> {
+ let isCompare = 1;
+}
+
// An alias of a RotateSelectRIEf, but with different register sizes.
class RotateSelectAliasRIEf<RegisterOperand cls1, RegisterOperand cls2>
: Alias<6, (outs cls1:$R1),
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td
index eb416036bf..6524e442b6 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -1176,12 +1176,13 @@ let Defs = [CC] in {
def TMHL : CompareRI<"tmhl", 0xA73, z_tm_reg, GRH32, imm32ll16>;
def TMHH : CompareRI<"tmhh", 0xA72, z_tm_reg, GRH32, imm32lh16>;
+ def TMLL64 : CompareAliasRI<z_tm_reg, GR64, imm64ll16>;
+ def TMLH64 : CompareAliasRI<z_tm_reg, GR64, imm64lh16>;
+ def TMHL64 : CompareAliasRI<z_tm_reg, GR64, imm64hl16>;
+ def TMHH64 : CompareAliasRI<z_tm_reg, GR64, imm64hh16>;
+
defm TM : CompareSIPair<"tm", 0x91, 0xEB51, z_tm_mem, anyextloadi8, imm32zx8>;
}
-def : CompareGR64RI<TMLL, z_tm_reg, imm64ll16, subreg_l32>;
-def : CompareGR64RI<TMLH, z_tm_reg, imm64lh16, subreg_l32>;
-def : CompareGR64RI<TMHL, z_tm_reg, imm64hl16, subreg_h32>;
-def : CompareGR64RI<TMHH, z_tm_reg, imm64hh16, subreg_h32>;
//===----------------------------------------------------------------------===//
// Prefetch
diff --git a/lib/Target/SystemZ/SystemZPatterns.td b/lib/Target/SystemZ/SystemZPatterns.td
index f3ca60b27a..7706351e54 100644
--- a/lib/Target/SystemZ/SystemZPatterns.td
+++ b/lib/Target/SystemZ/SystemZPatterns.td
@@ -112,14 +112,6 @@ multiclass CondStores64<Instruction insn, Instruction insninv,
uimm8zx4:$valid, uimm8zx4:$cc)>;
}
-// INSN performs a comparison between a 32-bit register and a constant.
-// Record that it is equivalent to comparing subreg SUBREG of a GR64 with IMM.
-class CompareGR64RI<Instruction insn, SDPatternOperator compare,
- Immediate imm, SubRegIndex subreg>
- : Pat<(compare GR64:$R1, imm:$I2),
- (insn (EXTRACT_SUBREG GR64:$R1, subreg),
- (imm.OperandTransform imm:$I2))>;
-
// Try to use MVC instruction INSN for a load of type LOAD followed by a store
// of the same size. VT is the type of the intermediate (legalized) value and
// LENGTH is the number of bytes loaded by LOAD.