This first step just adds definitions for SLLK, SRLK and SRAK.
The next patch will actually make use of them during codegen.
insn-bad.s tests that some form of error is reported when using these
instructions on z10. More work is needed to get the "instruction requires:
distinct-ops" that we'd ideally like, so I've stubbed that part out for now.
I'll come back and make it mandatory once the necessary changes are in.
llvm-svn: 186680
include "llvm/Target/Target.td"
//===----------------------------------------------------------------------===//
-// SystemZ supported processors
+// SystemZ supported processors and features
//===----------------------------------------------------------------------===//
-class Proc<string Name, list<SubtargetFeature> Features>
- : Processor<Name, NoItineraries, Features>;
-
-def : Proc<"z10", []>;
+include "SystemZProcessors.td"
//===----------------------------------------------------------------------===//
// Register file description
}
class ShiftRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
- RegisterOperand cls, AddressingMode mode>
- : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2),
+ RegisterOperand cls>
+ : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, shift12only:$BD2),
mnemonic#"\t$R1, $BD2",
- [(set cls:$R1, (operator cls:$R1src, mode:$BD2))]> {
+ [(set cls:$R1, (operator cls:$R1src, shift12only:$BD2))]> {
let R3 = 0;
let Constraints = "$R1 = $R1src";
let DisableEncoding = "$R1src";
}
class ShiftRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
- RegisterOperand cls, AddressingMode mode>
- : InstRSY<opcode, (outs cls:$R1), (ins cls:$R3, mode:$BD2),
+ RegisterOperand cls>
+ : InstRSY<opcode, (outs cls:$R1), (ins cls:$R3, shift20only:$BD2),
mnemonic#"\t$R1, $R3, $BD2",
- [(set cls:$R1, (operator cls:$R3, mode:$BD2))]>;
+ [(set cls:$R1, (operator cls:$R3, shift20only:$BD2))]>;
+
+multiclass ShiftRSAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
+ SDPatternOperator operator, RegisterOperand cls> {
+ def K : ShiftRSY<mnemonic##"k", opcode2, null_frag, cls>,
+ Requires<[FeatureDistinctOps]>;
+ def "" : ShiftRS<mnemonic, opcode1, operator, cls>;
+}
class CompareRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
RegisterOperand cls1, RegisterOperand cls2>
// Shift left.
let neverHasSideEffects = 1 in {
- def SLL : ShiftRS <"sll", 0x89, shl, GR32, shift12only>;
- def SLLG : ShiftRSY<"sllg", 0xEB0D, shl, GR64, shift20only>;
+ defm SLL : ShiftRSAndK<"sll", 0x89, 0xEBDF, shl, GR32>;
+ def SLLG : ShiftRSY<"sllg", 0xEB0D, shl, GR64>;
}
// Logical shift right.
let neverHasSideEffects = 1 in {
- def SRL : ShiftRS <"srl", 0x88, srl, GR32, shift12only>;
- def SRLG : ShiftRSY<"srlg", 0xEB0C, srl, GR64, shift20only>;
+ defm SRL : ShiftRSAndK<"srl", 0x88, 0xEBDE, srl, GR32>;
+ def SRLG : ShiftRSY<"srlg", 0xEB0C, srl, GR64>;
}
// Arithmetic shift right.
let Defs = [CC] in {
- def SRA : ShiftRS <"sra", 0x8A, sra, GR32, shift12only>;
- def SRAG : ShiftRSY<"srag", 0xEB0A, sra, GR64, shift20only>;
+ defm SRA : ShiftRSAndK<"sra", 0x8A, 0xEBDC, sra, GR32>;
+ def SRAG : ShiftRSY<"srag", 0xEB0A, sra, GR64>;
}
// Rotate left.
let neverHasSideEffects = 1 in {
- def RLL : ShiftRSY<"rll", 0xEB1D, rotl, GR32, shift20only>;
- def RLLG : ShiftRSY<"rllg", 0xEB1C, rotl, GR64, shift20only>;
+ def RLL : ShiftRSY<"rll", 0xEB1D, rotl, GR32>;
+ def RLLG : ShiftRSY<"rllg", 0xEB1C, rotl, GR64>;
}
// Rotate second operand left and inserted selected bits into first operand.
--- /dev/null
+//===-- SystemZ.td - SystemZ processors and features ---------*- tblgen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Processor and feature definitions.
+//
+//===----------------------------------------------------------------------===//
+
+class SystemZFeature<string extname, string intname, string desc>
+ : Predicate<"Subtarget.has"##intname##"()">,
+ AssemblerPredicate<"Feature"##intname, extname>,
+ SubtargetFeature<extname, "Has"##intname, "true", desc>;
+
+def FeatureDistinctOps : SystemZFeature<
+ "distinct-ops", "DistinctOps",
+ "Assume that the distinct-operands facility is installed"
+>;
+
+def : Processor<"z10", NoItineraries, []>;
+def : Processor<"z196", NoItineraries, [FeatureDistinctOps]>;
+def : Processor<"zEC12", NoItineraries, [FeatureDistinctOps]>;
#include "SystemZSubtarget.h"
#include "llvm/IR/GlobalValue.h"
+#include "MCTargetDesc/SystemZMCTargetDesc.h"
#define GET_SUBTARGETINFO_TARGET_DESC
#define GET_SUBTARGETINFO_CTOR
SystemZSubtarget::SystemZSubtarget(const std::string &TT,
const std::string &CPU,
const std::string &FS)
- : SystemZGenSubtargetInfo(TT, CPU, FS), TargetTriple(TT) {
+ : SystemZGenSubtargetInfo(TT, CPU, FS), HasDistinctOps(false),
+ TargetTriple(TT) {
std::string CPUName = CPU;
if (CPUName.empty())
CPUName = "z10";
class StringRef;
class SystemZSubtarget : public SystemZGenSubtargetInfo {
+protected:
+ bool HasDistinctOps;
+
private:
Triple TargetTriple;
// Automatically generated by tblgen.
void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
+ // Return true if the target has the distinct-operands facility.
+ bool hasDistinctOps() const { return HasDistinctOps; }
+
// Return true if GV can be accessed using LARL for reloc model RM
// and code model CM.
bool isPC32DBLSymbol(const GlobalValue *GV, Reloc::Model RM,
# Test instructions that don't have PC-relative operands.
-# RUN: llvm-mc --disassemble %s -triple=s390x-linux-gnu | FileCheck %s
+# RUN: llvm-mc --disassemble %s -triple=s390x-linux-gnu -mcpu=zEC12 | FileCheck %s
# CHECK: adbr %f0, %f0
0xb3 0x1a 0x00 0x00
# CHECK: sllg %r0, %r0, 524287(%r15)
0xeb 0x00 0xff 0xff 0x7f 0x0d
+# CHECK: sllk %r0, %r0, 0
+0xeb 0x00 0x00 0x00 0x00 0xdf
+
+# CHECK: sllk %r15, %r1, 0
+0xeb 0xf1 0x00 0x00 0x00 0xdf
+
+# CHECK: sllk %r1, %r15, 0
+0xeb 0x1f 0x00 0x00 0x00 0xdf
+
+# CHECK: sllk %r15, %r15, 0
+0xeb 0xff 0x00 0x00 0x00 0xdf
+
+# CHECK: sllk %r0, %r0, -524288
+0xeb 0x00 0x00 0x00 0x80 0xdf
+
+# CHECK: sllk %r0, %r0, -1
+0xeb 0x00 0x0f 0xff 0xff 0xdf
+
+# CHECK: sllk %r0, %r0, 1
+0xeb 0x00 0x00 0x01 0x00 0xdf
+
+# CHECK: sllk %r0, %r0, 524287
+0xeb 0x00 0x0f 0xff 0x7f 0xdf
+
+# CHECK: sllk %r0, %r0, 0(%r1)
+0xeb 0x00 0x10 0x00 0x00 0xdf
+
+# CHECK: sllk %r0, %r0, 0(%r15)
+0xeb 0x00 0xf0 0x00 0x00 0xdf
+
+# CHECK: sllk %r0, %r0, 524287(%r1)
+0xeb 0x00 0x1f 0xff 0x7f 0xdf
+
+# CHECK: sllk %r0, %r0, 524287(%r15)
+0xeb 0x00 0xff 0xff 0x7f 0xdf
+
# CHECK: sll %r0, 0
0x89 0x00 0x00 0x00
# CHECK: srag %r0, %r0, 524287(%r15)
0xeb 0x00 0xff 0xff 0x7f 0x0a
+# CHECK: srak %r0, %r0, 0
+0xeb 0x00 0x00 0x00 0x00 0xdc
+
+# CHECK: srak %r15, %r1, 0
+0xeb 0xf1 0x00 0x00 0x00 0xdc
+
+# CHECK: srak %r1, %r15, 0
+0xeb 0x1f 0x00 0x00 0x00 0xdc
+
+# CHECK: srak %r15, %r15, 0
+0xeb 0xff 0x00 0x00 0x00 0xdc
+
+# CHECK: srak %r0, %r0, -524288
+0xeb 0x00 0x00 0x00 0x80 0xdc
+
+# CHECK: srak %r0, %r0, -1
+0xeb 0x00 0x0f 0xff 0xff 0xdc
+
+# CHECK: srak %r0, %r0, 1
+0xeb 0x00 0x00 0x01 0x00 0xdc
+
+# CHECK: srak %r0, %r0, 524287
+0xeb 0x00 0x0f 0xff 0x7f 0xdc
+
+# CHECK: srak %r0, %r0, 0(%r1)
+0xeb 0x00 0x10 0x00 0x00 0xdc
+
+# CHECK: srak %r0, %r0, 0(%r15)
+0xeb 0x00 0xf0 0x00 0x00 0xdc
+
+# CHECK: srak %r0, %r0, 524287(%r1)
+0xeb 0x00 0x1f 0xff 0x7f 0xdc
+
+# CHECK: srak %r0, %r0, 524287(%r15)
+0xeb 0x00 0xff 0xff 0x7f 0xdc
+
# CHECK: sra %r0, 0
0x8a 0x00 0x00 0x00
# CHECK: srlg %r0, %r0, 524287(%r15)
0xeb 0x00 0xff 0xff 0x7f 0x0c
+# CHECK: srlk %r0, %r0, 0
+0xeb 0x00 0x00 0x00 0x00 0xde
+
+# CHECK: srlk %r15, %r1, 0
+0xeb 0xf1 0x00 0x00 0x00 0xde
+
+# CHECK: srlk %r1, %r15, 0
+0xeb 0x1f 0x00 0x00 0x00 0xde
+
+# CHECK: srlk %r15, %r15, 0
+0xeb 0xff 0x00 0x00 0x00 0xde
+
+# CHECK: srlk %r0, %r0, -524288
+0xeb 0x00 0x00 0x00 0x80 0xde
+
+# CHECK: srlk %r0, %r0, -1
+0xeb 0x00 0x0f 0xff 0xff 0xde
+
+# CHECK: srlk %r0, %r0, 1
+0xeb 0x00 0x00 0x01 0x00 0xde
+
+# CHECK: srlk %r0, %r0, 524287
+0xeb 0x00 0x0f 0xff 0x7f 0xde
+
+# CHECK: srlk %r0, %r0, 0(%r1)
+0xeb 0x00 0x10 0x00 0x00 0xde
+
+# CHECK: srlk %r0, %r0, 0(%r15)
+0xeb 0x00 0xf0 0x00 0x00 0xde
+
+# CHECK: srlk %r0, %r0, 524287(%r1)
+0xeb 0x00 0x1f 0xff 0x7f 0xde
+
+# CHECK: srlk %r0, %r0, 524287(%r15)
+0xeb 0x00 0xff 0xff 0x7f 0xde
+
# CHECK: srl %r0, 0
0x88 0x00 0x00 0x00
--- /dev/null
+# For z196 only.
+# RUN: not llvm-mc -triple s390x-linux-gnu -mcpu=z196 < %s 2> %t
+# RUN: FileCheck < %t %s
+#CHECK: error: invalid operand
+#CHECK: sllk %r0,%r0,-524289
+#CHECK: error: invalid operand
+#CHECK: sllk %r0,%r0,524288
+#CHECK: error: %r0 used in an address
+#CHECK: sllk %r0,%r0,0(%r0)
+#CHECK: error: invalid use of indexed addressing
+#CHECK: sllk %r0,%r0,0(%r1,%r2)
+
+ sllk %r0,%r0,-524289
+ sllk %r0,%r0,524288
+ sllk %r0,%r0,0(%r0)
+ sllk %r0,%r0,0(%r1,%r2)
+
+#CHECK: error: invalid operand
+#CHECK: srak %r0,%r0,-524289
+#CHECK: error: invalid operand
+#CHECK: srak %r0,%r0,524288
+#CHECK: error: %r0 used in an address
+#CHECK: srak %r0,%r0,0(%r0)
+#CHECK: error: invalid use of indexed addressing
+#CHECK: srak %r0,%r0,0(%r1,%r2)
+
+ srak %r0,%r0,-524289
+ srak %r0,%r0,524288
+ srak %r0,%r0,0(%r0)
+ srak %r0,%r0,0(%r1,%r2)
+
+#CHECK: error: invalid operand
+#CHECK: srlk %r0,%r0,-524289
+#CHECK: error: invalid operand
+#CHECK: srlk %r0,%r0,524288
+#CHECK: error: %r0 used in an address
+#CHECK: srlk %r0,%r0,0(%r0)
+#CHECK: error: invalid use of indexed addressing
+#CHECK: srlk %r0,%r0,0(%r1,%r2)
+
+ srlk %r0,%r0,-524289
+ srlk %r0,%r0,524288
+ srlk %r0,%r0,0(%r0)
+ srlk %r0,%r0,0(%r1,%r2)
-# RUN: not llvm-mc -triple s390x-linux-gnu < %s 2> %t
+# For z10 only.
+# RUN: not llvm-mc -triple s390x-linux-gnu -mcpu=z10 < %s 2> %t
# RUN: FileCheck < %t %s
#CHECK: error: invalid operand
sllg %r0,%r0,0(%r0)
sllg %r0,%r0,0(%r1,%r2)
+#CHECK: error: {{(instruction requires: distinct-ops)?}}
+#CHECK: sllk %r2,%r3,4(%r5)
+
+ sllk %r2,%r3,4(%r5)
+
#CHECK: error: invalid operand
#CHECK: sly %r0, -524289
#CHECK: error: invalid operand
srag %r0,%r0,0(%r0)
srag %r0,%r0,0(%r1,%r2)
+#CHECK: error: {{(instruction requires: distinct-ops)?}}
+#CHECK: srak %r2,%r3,4(%r5)
+
+ srak %r2,%r3,4(%r5)
+
#CHECK: error: invalid operand
#CHECK: srl %r0,-1
#CHECK: error: invalid operand
srlg %r0,%r0,0(%r0)
srlg %r0,%r0,0(%r1,%r2)
+#CHECK: error: {{(instruction requires: distinct-ops)?}}
+#CHECK: srlk %r2,%r3,4(%r5)
+
+ srlk %r2,%r3,4(%r5)
+
#CHECK: error: invalid operand
#CHECK: st %r0, -1
#CHECK: error: invalid operand
--- /dev/null
+# For z196 and above.
+# RUN: llvm-mc -triple s390x-linux-gnu -mcpu=z196 -show-encoding %s | FileCheck %s
+
+#CHECK: sllk %r0, %r0, 0 # encoding: [0xeb,0x00,0x00,0x00,0x00,0xdf]
+#CHECK: sllk %r15, %r1, 0 # encoding: [0xeb,0xf1,0x00,0x00,0x00,0xdf]
+#CHECK: sllk %r1, %r15, 0 # encoding: [0xeb,0x1f,0x00,0x00,0x00,0xdf]
+#CHECK: sllk %r15, %r15, 0 # encoding: [0xeb,0xff,0x00,0x00,0x00,0xdf]
+#CHECK: sllk %r0, %r0, -524288 # encoding: [0xeb,0x00,0x00,0x00,0x80,0xdf]
+#CHECK: sllk %r0, %r0, -1 # encoding: [0xeb,0x00,0x0f,0xff,0xff,0xdf]
+#CHECK: sllk %r0, %r0, 1 # encoding: [0xeb,0x00,0x00,0x01,0x00,0xdf]
+#CHECK: sllk %r0, %r0, 524287 # encoding: [0xeb,0x00,0x0f,0xff,0x7f,0xdf]
+#CHECK: sllk %r0, %r0, 0(%r1) # encoding: [0xeb,0x00,0x10,0x00,0x00,0xdf]
+#CHECK: sllk %r0, %r0, 0(%r15) # encoding: [0xeb,0x00,0xf0,0x00,0x00,0xdf]
+#CHECK: sllk %r0, %r0, 524287(%r1) # encoding: [0xeb,0x00,0x1f,0xff,0x7f,0xdf]
+#CHECK: sllk %r0, %r0, 524287(%r15) # encoding: [0xeb,0x00,0xff,0xff,0x7f,0xdf]
+
+ sllk %r0,%r0,0
+ sllk %r15,%r1,0
+ sllk %r1,%r15,0
+ sllk %r15,%r15,0
+ sllk %r0,%r0,-524288
+ sllk %r0,%r0,-1
+ sllk %r0,%r0,1
+ sllk %r0,%r0,524287
+ sllk %r0,%r0,0(%r1)
+ sllk %r0,%r0,0(%r15)
+ sllk %r0,%r0,524287(%r1)
+ sllk %r0,%r0,524287(%r15)
+
+#CHECK: srak %r0, %r0, 0 # encoding: [0xeb,0x00,0x00,0x00,0x00,0xdc]
+#CHECK: srak %r15, %r1, 0 # encoding: [0xeb,0xf1,0x00,0x00,0x00,0xdc]
+#CHECK: srak %r1, %r15, 0 # encoding: [0xeb,0x1f,0x00,0x00,0x00,0xdc]
+#CHECK: srak %r15, %r15, 0 # encoding: [0xeb,0xff,0x00,0x00,0x00,0xdc]
+#CHECK: srak %r0, %r0, -524288 # encoding: [0xeb,0x00,0x00,0x00,0x80,0xdc]
+#CHECK: srak %r0, %r0, -1 # encoding: [0xeb,0x00,0x0f,0xff,0xff,0xdc]
+#CHECK: srak %r0, %r0, 1 # encoding: [0xeb,0x00,0x00,0x01,0x00,0xdc]
+#CHECK: srak %r0, %r0, 524287 # encoding: [0xeb,0x00,0x0f,0xff,0x7f,0xdc]
+#CHECK: srak %r0, %r0, 0(%r1) # encoding: [0xeb,0x00,0x10,0x00,0x00,0xdc]
+#CHECK: srak %r0, %r0, 0(%r15) # encoding: [0xeb,0x00,0xf0,0x00,0x00,0xdc]
+#CHECK: srak %r0, %r0, 524287(%r1) # encoding: [0xeb,0x00,0x1f,0xff,0x7f,0xdc]
+#CHECK: srak %r0, %r0, 524287(%r15) # encoding: [0xeb,0x00,0xff,0xff,0x7f,0xdc]
+
+ srak %r0,%r0,0
+ srak %r15,%r1,0
+ srak %r1,%r15,0
+ srak %r15,%r15,0
+ srak %r0,%r0,-524288
+ srak %r0,%r0,-1
+ srak %r0,%r0,1
+ srak %r0,%r0,524287
+ srak %r0,%r0,0(%r1)
+ srak %r0,%r0,0(%r15)
+ srak %r0,%r0,524287(%r1)
+ srak %r0,%r0,524287(%r15)
+
+#CHECK: srlk %r0, %r0, 0 # encoding: [0xeb,0x00,0x00,0x00,0x00,0xde]
+#CHECK: srlk %r15, %r1, 0 # encoding: [0xeb,0xf1,0x00,0x00,0x00,0xde]
+#CHECK: srlk %r1, %r15, 0 # encoding: [0xeb,0x1f,0x00,0x00,0x00,0xde]
+#CHECK: srlk %r15, %r15, 0 # encoding: [0xeb,0xff,0x00,0x00,0x00,0xde]
+#CHECK: srlk %r0, %r0, -524288 # encoding: [0xeb,0x00,0x00,0x00,0x80,0xde]
+#CHECK: srlk %r0, %r0, -1 # encoding: [0xeb,0x00,0x0f,0xff,0xff,0xde]
+#CHECK: srlk %r0, %r0, 1 # encoding: [0xeb,0x00,0x00,0x01,0x00,0xde]
+#CHECK: srlk %r0, %r0, 524287 # encoding: [0xeb,0x00,0x0f,0xff,0x7f,0xde]
+#CHECK: srlk %r0, %r0, 0(%r1) # encoding: [0xeb,0x00,0x10,0x00,0x00,0xde]
+#CHECK: srlk %r0, %r0, 0(%r15) # encoding: [0xeb,0x00,0xf0,0x00,0x00,0xde]
+#CHECK: srlk %r0, %r0, 524287(%r1) # encoding: [0xeb,0x00,0x1f,0xff,0x7f,0xde]
+#CHECK: srlk %r0, %r0, 524287(%r15) # encoding: [0xeb,0x00,0xff,0xff,0x7f,0xde]
+
+ srlk %r0,%r0,0
+ srlk %r15,%r1,0
+ srlk %r1,%r15,0
+ srlk %r15,%r15,0
+ srlk %r0,%r0,-524288
+ srlk %r0,%r0,-1
+ srlk %r0,%r0,1
+ srlk %r0,%r0,524287
+ srlk %r0,%r0,0(%r1)
+ srlk %r0,%r0,0(%r15)
+ srlk %r0,%r0,524287(%r1)
+ srlk %r0,%r0,524287(%r15)
+# For z10 and above.
# RUN: llvm-mc -triple s390x-linux-gnu -show-encoding %s | FileCheck %s
#CHECK: a %r0, 0 # encoding: [0x5a,0x00,0x00,0x00]