1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

[SystemZ] Support load-and-trap instructions

This adds support for the instructions provided with the
load-and-trap facility.

llvm-svn: 288030
This commit is contained in:
Ulrich Weigand 2016-11-28 13:59:22 +00:00
parent 0487d18102
commit 64c39ae7f5
15 changed files with 835 additions and 7 deletions

View File

@ -28,6 +28,7 @@ using namespace llvm;
#define DEBUG_TYPE "systemz-elim-compare"
STATISTIC(BranchOnCounts, "Number of branch-on-count instructions");
STATISTIC(LoadAndTraps, "Number of load-and-trap instructions");
STATISTIC(EliminatedComparisons, "Number of eliminated comparisons");
STATISTIC(FusedComparisons, "Number of fused compare-and-branch instructions");
@ -73,6 +74,8 @@ private:
Reference getRegReferences(MachineInstr &MI, unsigned Reg);
bool convertToBRCT(MachineInstr &MI, MachineInstr &Compare,
SmallVectorImpl<MachineInstr *> &CCUsers);
bool convertToLoadAndTrap(MachineInstr &MI, MachineInstr &Compare,
SmallVectorImpl<MachineInstr *> &CCUsers);
bool convertToLoadAndTest(MachineInstr &MI);
bool adjustCCMasksForInstr(MachineInstr &MI, MachineInstr &Compare,
SmallVectorImpl<MachineInstr *> &CCUsers);
@ -225,6 +228,48 @@ bool SystemZElimCompare::convertToBRCT(
return true;
}
// Compare compares the result of MI against zero. If MI is a suitable load
// instruction and if CCUsers is a single conditional trap on zero, eliminate
// the load and convert the branch to a load-and-trap. Return true on success.
bool SystemZElimCompare::convertToLoadAndTrap(
MachineInstr &MI, MachineInstr &Compare,
SmallVectorImpl<MachineInstr *> &CCUsers) {
unsigned LATOpcode = TII->getLoadAndTrap(MI.getOpcode());
if (!LATOpcode)
return false;
// Check whether we have a single CondTrap that traps on zero.
if (CCUsers.size() != 1)
return false;
MachineInstr *Branch = CCUsers[0];
if (Branch->getOpcode() != SystemZ::CondTrap ||
Branch->getOperand(0).getImm() != SystemZ::CCMASK_ICMP ||
Branch->getOperand(1).getImm() != SystemZ::CCMASK_CMP_EQ)
return false;
// We already know that there are no references to the register between
// MI and Compare. Make sure that there are also no references between
// Compare and Branch.
unsigned SrcReg = getCompareSourceReg(Compare);
MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch;
for (++MBBI; MBBI != MBBE; ++MBBI)
if (getRegReferences(*MBBI, SrcReg))
return false;
// The transformation is OK. Rebuild Branch as a load-and-trap.
MachineOperand Target(Branch->getOperand(2));
while (Branch->getNumOperands())
Branch->RemoveOperand(0);
Branch->setDesc(TII->get(LATOpcode));
MachineInstrBuilder(*Branch->getParent()->getParent(), Branch)
.addOperand(MI.getOperand(0))
.addOperand(MI.getOperand(1))
.addOperand(MI.getOperand(2))
.addOperand(MI.getOperand(3));
MI.eraseFromParent();
return true;
}
// If MI is a load instruction, try to convert it into a LOAD AND TEST.
// Return true on success.
bool SystemZElimCompare::convertToLoadAndTest(MachineInstr &MI) {
@ -353,11 +398,17 @@ bool SystemZElimCompare::optimizeCompareZero(
MachineInstr &MI = *MBBI;
if (resultTests(MI, SrcReg)) {
// Try to remove both MI and Compare by converting a branch to BRCT(G).
// We don't care in this case whether CC is modified between MI and
// Compare.
if (!CCRefs.Use && !SrcRefs && convertToBRCT(MI, Compare, CCUsers)) {
BranchOnCounts += 1;
return true;
// or a load-and-trap instruction. We don't care in this case whether
// CC is modified between MI and Compare.
if (!CCRefs.Use && !SrcRefs) {
if (convertToBRCT(MI, Compare, CCUsers)) {
BranchOnCounts += 1;
return true;
}
if (convertToLoadAndTrap(MI, Compare, CCUsers)) {
LoadAndTraps += 1;
return true;
}
}
// Try to eliminate Compare by reusing a CC result from MI.
if ((!CCRefs && convertToLoadAndTest(MI)) ||

View File

@ -84,6 +84,11 @@ def Arch9NewFeatures : SystemZFeatureList<[
//
//===----------------------------------------------------------------------===//
def FeatureLoadAndTrap : SystemZFeature<
"load-and-trap", "LoadAndTrap",
"Assume that the load-and-trap facility is installed"
>;
def FeatureMiscellaneousExtensions : SystemZFeature<
"miscellaneous-extensions", "MiscellaneousExtensions",
"Assume that the miscellaneous-extensions facility is installed"
@ -100,6 +105,7 @@ def FeatureTransactionalExecution : SystemZFeature<
>;
def Arch10NewFeatures : SystemZFeatureList<[
FeatureLoadAndTrap,
FeatureMiscellaneousExtensions,
FeatureProcessorAssist,
FeatureTransactionalExecution

View File

@ -1678,6 +1678,25 @@ unsigned SystemZInstrInfo::getFusedCompare(unsigned Opcode,
return 0;
}
unsigned SystemZInstrInfo::getLoadAndTrap(unsigned Opcode) const {
if (!STI.hasLoadAndTrap())
return 0;
switch (Opcode) {
case SystemZ::L:
case SystemZ::LY:
return SystemZ::LAT;
case SystemZ::LG:
return SystemZ::LGAT;
case SystemZ::LFH:
return SystemZ::LFHAT;
case SystemZ::LLGF:
return SystemZ::LLGFAT;
case SystemZ::LLGT:
return SystemZ::LLGTAT;
}
return 0;
}
void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned Reg, uint64_t Value) const {

View File

@ -286,6 +286,10 @@ public:
SystemZII::FusedCompareType Type,
const MachineInstr *MI = nullptr) const;
// If Opcode is a LOAD opcode for with an associated LOAD AND TRAP
// operation exists, returh the opcode for the latter, otherwise return 0.
unsigned getLoadAndTrap(unsigned Opcode) const;
// Emit code before MBBI in MI to move immediate value Value into
// physical register Reg.
void loadImmediate(MachineBasicBlock &MBB,

View File

@ -426,6 +426,13 @@ let Predicates = [FeatureLoadAndZeroRightmostByte] in {
(LZRG bdxaddr20only:$src)>;
}
// Load and trap.
let Predicates = [FeatureLoadAndTrap] in {
def LAT : UnaryRXY<"lat", 0xE39F, null_frag, GR32, 4>;
def LFHAT : UnaryRXY<"lfhat", 0xE3C8, null_frag, GRH32, 4>;
def LGAT : UnaryRXY<"lgat", 0xE385, null_frag, GR64, 8>;
}
// Register stores.
let SimpleBDXStore = 1 in {
// Expands to ST, STY or STFH, depending on the choice of register.
@ -662,6 +669,12 @@ let Predicates = [FeatureLoadAndZeroRightmostByte] in {
(LLZRGF bdxaddr20only:$src)>;
}
// Load and trap.
let Predicates = [FeatureLoadAndTrap] in {
def LLGFAT : UnaryRXY<"llgfat", 0xE39D, null_frag, GR64, 4>;
def LLGTAT : UnaryRXY<"llgtat", 0xE39C, null_frag, GR64, 4>;
}
//===----------------------------------------------------------------------===//
// Truncations
//===----------------------------------------------------------------------===//

View File

@ -202,6 +202,9 @@ def : InstRW<[FXa], (instregex "LR(Mux)?$")>;
// Load and zero rightmost byte
def : InstRW<[LSU], (instregex "LZR(F|G)$")>;
// Load and trap
def : InstRW<[FXb, LSU, Lat5], (instregex "L(FH|G)?AT$")>;
// Load and test
def : InstRW<[FXa, LSU, Lat5], (instregex "LT(G)?$")>;
def : InstRW<[FXa], (instregex "LT(G)?R$")>;
@ -256,6 +259,9 @@ def : InstRW<[LSU], (instregex "LLG(C|H|F|T|HRL|FRL)$")>;
// Load and zero rightmost byte
def : InstRW<[LSU], (instregex "LLZRGF$")>;
// Load and trap
def : InstRW<[FXb, LSU, Lat5], (instregex "LLG(F|T)?AT$")>;
//===----------------------------------------------------------------------===//
// Truncations
//===----------------------------------------------------------------------===//

View File

@ -175,6 +175,9 @@ def : InstRW<[FXU], (instregex "LG(F|H)I$")>;
def : InstRW<[FXU], (instregex "LHI(Mux)?$")>;
def : InstRW<[FXU], (instregex "LR(Mux)?$")>;
// Load and trap
def : InstRW<[FXU, LSU, Lat5], (instregex "L(FH|G)?AT$")>;
// Load and test
def : InstRW<[FXU, LSU, Lat5], (instregex "LT(G)?$")>;
def : InstRW<[FXU], (instregex "LT(G)?R$")>;
@ -224,6 +227,9 @@ def : InstRW<[FXU, LSU, Lat5], (instregex "LL(C|H)H$")>;
def : InstRW<[LSU], (instregex "LLHRL$")>;
def : InstRW<[LSU], (instregex "LLG(C|H|F|T|HRL|FRL)$")>;
// Load and trap
def : InstRW<[FXU, LSU, Lat5], (instregex "LLG(F|T)?AT$")>;
//===----------------------------------------------------------------------===//
// Truncations
//===----------------------------------------------------------------------===//

View File

@ -39,8 +39,8 @@ SystemZSubtarget::SystemZSubtarget(const Triple &TT, const std::string &CPU,
HasLoadStoreOnCond(false), HasHighWord(false), HasFPExtension(false),
HasPopulationCount(false), HasFastSerialization(false),
HasInterlockedAccess1(false), HasMiscellaneousExtensions(false),
HasTransactionalExecution(false), HasProcessorAssist(false),
HasVector(false), HasLoadStoreOnCond2(false),
HasLoadAndTrap(false), HasTransactionalExecution(false),
HasProcessorAssist(false), HasVector(false), HasLoadStoreOnCond2(false),
HasLoadAndZeroRightmostByte(false),
TargetTriple(TT), InstrInfo(initializeSubtargetDependencies(CPU, FS)),
TLInfo(TM, *this), TSInfo(), FrameLowering() {}

View File

@ -42,6 +42,7 @@ protected:
bool HasFastSerialization;
bool HasInterlockedAccess1;
bool HasMiscellaneousExtensions;
bool HasLoadAndTrap;
bool HasTransactionalExecution;
bool HasProcessorAssist;
bool HasVector;
@ -113,6 +114,9 @@ public:
return HasMiscellaneousExtensions;
}
// Return true if the target has the load-and-trap facility.
bool hasLoadAndTrap() const { return HasLoadAndTrap; }
// Return true if the target has the transactional-execution facility.
bool hasTransactionalExecution() const { return HasTransactionalExecution; }

View File

@ -0,0 +1,157 @@
; Test load-and-trap instructions (LAT/LGAT)
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 | FileCheck %s
declare void @llvm.trap()
; Check LAT with no displacement.
define i32 @f1(i32 *%ptr) {
; CHECK-LABEL: f1:
; CHECK: lat %r2, 0(%r2)
; CHECK: br %r14
entry:
%val = load i32, i32 *%ptr
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i32 %val
}
; Check the high end of the LAT range.
define i32 @f2(i32 *%src) {
; CHECK-LABEL: f2:
; CHECK: lat %r2, 524284(%r2)
; CHECK: br %r14
%ptr = getelementptr i32, i32 *%src, i64 131071
%val = load i32, i32 *%ptr
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i32 %val
}
; Check the next word up, which needs separate address logic.
; Other sequences besides this one would be OK.
define i32 @f3(i32 *%src) {
; CHECK-LABEL: f3:
; CHECK: agfi %r2, 524288
; CHECK: lat %r2, 0(%r2)
; CHECK: br %r14
%ptr = getelementptr i32, i32 *%src, i64 131072
%val = load i32, i32 *%ptr
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i32 %val
}
; Check that LAT allows an index.
define i32 @f4(i64 %src, i64 %index) {
; CHECK-LABEL: f4:
; CHECK: lat %r2, 524287(%r3,%r2)
; CHECK: br %r14
%add1 = add i64 %src, %index
%add2 = add i64 %add1, 524287
%ptr = inttoptr i64 %add2 to i32 *
%val = load i32, i32 *%ptr
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i32 %val
}
; Check LGAT with no displacement.
define i64 @f5(i64 *%ptr) {
; CHECK-LABEL: f5:
; CHECK: lgat %r2, 0(%r2)
; CHECK: br %r14
entry:
%val = load i64, i64 *%ptr
%cmp = icmp eq i64 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %val
}
; Check the high end of the LGAT range.
define i64 @f6(i64 *%src) {
; CHECK-LABEL: f6:
; CHECK: lgat %r2, 524280(%r2)
; CHECK: br %r14
%ptr = getelementptr i64, i64 *%src, i64 65535
%val = load i64, i64 *%ptr
%cmp = icmp eq i64 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %val
}
; Check the next word up, which needs separate address logic.
; Other sequences besides this one would be OK.
define i64 @f7(i64 *%src) {
; CHECK-LABEL: f7:
; CHECK: agfi %r2, 524288
; CHECK: lgat %r2, 0(%r2)
; CHECK: br %r14
%ptr = getelementptr i64, i64 *%src, i64 65536
%val = load i64, i64 *%ptr
%cmp = icmp eq i64 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %val
}
; Check that LGAT allows an index.
define i64 @f8(i64 %src, i64 %index) {
; CHECK-LABEL: f8:
; CHECK: lgat %r2, 524287(%r3,%r2)
; CHECK: br %r14
%add1 = add i64 %src, %index
%add2 = add i64 %add1, 524287
%ptr = inttoptr i64 %add2 to i64 *
%val = load i64, i64 *%ptr
%cmp = icmp eq i64 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %val
}

View File

@ -0,0 +1,170 @@
; Test load-and-trap instructions (LLGFAT/LLGFTAT)
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 | FileCheck %s
declare void @llvm.trap()
; Check LLGFAT with no displacement.
define i64 @f1(i32 *%ptr) {
; CHECK-LABEL: f1:
; CHECK: llgfat %r2, 0(%r2)
; CHECK: br %r14
entry:
%val = load i32, i32 *%ptr
%ext = zext i32 %val to i64
%cmp = icmp eq i64 %ext, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %ext
}
; Check the high end of the LLGFAT range.
define i64 @f2(i32 *%src) {
; CHECK-LABEL: f2:
; CHECK: llgfat %r2, 524284(%r2)
; CHECK: br %r14
%ptr = getelementptr i32, i32 *%src, i64 131071
%val = load i32, i32 *%ptr
%ext = zext i32 %val to i64
%cmp = icmp eq i64 %ext, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %ext
}
; Check the next word up, which needs separate address logic.
; Other sequences besides this one would be OK.
define i64 @f3(i32 *%src) {
; CHECK-LABEL: f3:
; CHECK: agfi %r2, 524288
; CHECK: llgfat %r2, 0(%r2)
; CHECK: br %r14
%ptr = getelementptr i32, i32 *%src, i64 131072
%val = load i32, i32 *%ptr
%ext = zext i32 %val to i64
%cmp = icmp eq i64 %ext, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %ext
}
; Check that LLGFAT allows an index.
define i64 @f4(i64 %src, i64 %index) {
; CHECK-LABEL: f4:
; CHECK: llgfat %r2, 524287(%r3,%r2)
; CHECK: br %r14
%add1 = add i64 %src, %index
%add2 = add i64 %add1, 524287
%ptr = inttoptr i64 %add2 to i32 *
%val = load i32, i32 *%ptr
%ext = zext i32 %val to i64
%cmp = icmp eq i64 %ext, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %ext
}
; Check LLGTAT with no displacement.
define i64 @f5(i32 *%ptr) {
; CHECK-LABEL: f5:
; CHECK: llgtat %r2, 0(%r2)
; CHECK: br %r14
entry:
%val = load i32, i32 *%ptr
%ext = zext i32 %val to i64
%and = and i64 %ext, 2147483647
%cmp = icmp eq i64 %and, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %and
}
; Check the high end of the LLGTAT range.
define i64 @f6(i32 *%src) {
; CHECK-LABEL: f6:
; CHECK: llgtat %r2, 524284(%r2)
; CHECK: br %r14
%ptr = getelementptr i32, i32 *%src, i64 131071
%val = load i32, i32 *%ptr
%ext = zext i32 %val to i64
%and = and i64 %ext, 2147483647
%cmp = icmp eq i64 %and, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %and
}
; Check the next word up, which needs separate address logic.
; Other sequences besides this one would be OK.
define i64 @f7(i32 *%src) {
; CHECK-LABEL: f7:
; CHECK: agfi %r2, 524288
; CHECK: llgtat %r2, 0(%r2)
; CHECK: br %r14
%ptr = getelementptr i32, i32 *%src, i64 131072
%val = load i32, i32 *%ptr
%ext = zext i32 %val to i64
%and = and i64 %ext, 2147483647
%cmp = icmp eq i64 %and, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %and
}
; Check that LLGTAT allows an index.
define i64 @f8(i64 %src, i64 %index) {
; CHECK-LABEL: f8:
; CHECK: llgtat %r2, 524287(%r3,%r2)
; CHECK: br %r14
%add1 = add i64 %src, %index
%add2 = add i64 %add1, 524287
%ptr = inttoptr i64 %add2 to i32 *
%val = load i32, i32 *%ptr
%ext = zext i32 %val to i64
%and = and i64 %ext, 2147483647
%cmp = icmp eq i64 %and, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
ret i64 %and
}

View File

@ -0,0 +1,92 @@
; Test load-and-trap instructions (LFHAT)
; See comments in asm-18.ll about testing high-word operations.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 \
; RUN: -no-integrated-as | FileCheck %s
declare void @llvm.trap()
; Check LAT with no displacement.
define void @f1(i32 *%ptr) {
; CHECK-LABEL: f1:
; CHECK: lfhat [[REG:%r[0-9]+]], 0(%r2)
; CHECK: stepa [[REG]]
; CHECK: br %r14
entry:
%val = load i32, i32 *%ptr
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
call void asm sideeffect "stepa $0", "h"(i32 %val)
ret void;
}
; Check the high end of the LAT range.
define void @f2(i32 *%src) {
; CHECK-LABEL: f2:
; CHECK: lfhat [[REG:%r[0-9]+]], 524284(%r2)
; CHECK: stepa [[REG]]
; CHECK: br %r14
%ptr = getelementptr i32, i32 *%src, i64 131071
%val = load i32, i32 *%ptr
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
call void asm sideeffect "stepa $0", "h"(i32 %val)
ret void;
}
; Check the next word up, which needs separate address logic.
; Other sequences besides this one would be OK.
define void @f3(i32 *%src) {
; CHECK-LABEL: f3:
; CHECK: agfi %r2, 524288
; CHECK: lfhat [[REG:%r[0-9]+]], 0(%r2)
; CHECK: stepa [[REG]]
; CHECK: br %r14
%ptr = getelementptr i32, i32 *%src, i64 131072
%val = load i32, i32 *%ptr
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
call void asm sideeffect "stepa $0", "h"(i32 %val)
ret void;
}
; Check that LAT allows an index.
define void @f4(i64 %src, i64 %index) {
; CHECK-LABEL: f4:
; CHECK: lfhat [[REG:%r[0-9]+]], 524287(%r3,%r2)
; CHECK: stepa [[REG]]
; CHECK: br %r14
%add1 = add i64 %src, %index
%add2 = add i64 %add1, 524287
%ptr = inttoptr i64 %add2 to i32 *
%val = load i32, i32 *%ptr
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
tail call void @llvm.trap()
unreachable
if.end: ; preds = %entry
call void asm sideeffect "stepa $0", "h"(i32 %val)
ret void;
}

View File

@ -5188,6 +5188,36 @@
# CHECK: lfh %r15, 0
0xe3 0xf0 0x00 0x00 0x00 0xca
# CHECK: lfhat %r0, -524288
0xe3 0x00 0x00 0x00 0x80 0xc8
# CHECK: lfhat %r0, -1
0xe3 0x00 0x0f 0xff 0xff 0xc8
# CHECK: lfhat %r0, 0
0xe3 0x00 0x00 0x00 0x00 0xc8
# CHECK: lfhat %r0, 1
0xe3 0x00 0x00 0x01 0x00 0xc8
# CHECK: lfhat %r0, 524287
0xe3 0x00 0x0f 0xff 0x7f 0xc8
# CHECK: lfhat %r0, 0(%r1)
0xe3 0x00 0x10 0x00 0x00 0xc8
# CHECK: lfhat %r0, 0(%r15)
0xe3 0x00 0xf0 0x00 0x00 0xc8
# CHECK: lfhat %r0, 524287(%r1,%r15)
0xe3 0x01 0xff 0xff 0x7f 0xc8
# CHECK: lfhat %r0, 524287(%r15,%r1)
0xe3 0x0f 0x1f 0xff 0x7f 0xc8
# CHECK: lfhat %r15, 0
0xe3 0xf0 0x00 0x00 0x00 0xc8
# CHECK: lgbr %r0, %r15
0xb9 0x06 0x00 0x0f
@ -5398,6 +5428,36 @@
# CHECK: lg %r15, 0
0xe3 0xf0 0x00 0x00 0x00 0x04
# CHECK: lgat %r0, -524288
0xe3 0x00 0x00 0x00 0x80 0x85
# CHECK: lgat %r0, -1
0xe3 0x00 0x0f 0xff 0xff 0x85
# CHECK: lgat %r0, 0
0xe3 0x00 0x00 0x00 0x00 0x85
# CHECK: lgat %r0, 1
0xe3 0x00 0x00 0x01 0x00 0x85
# CHECK: lgat %r0, 524287
0xe3 0x00 0x0f 0xff 0x7f 0x85
# CHECK: lgat %r0, 0(%r1)
0xe3 0x00 0x10 0x00 0x00 0x85
# CHECK: lgat %r0, 0(%r15)
0xe3 0x00 0xf0 0x00 0x00 0x85
# CHECK: lgat %r0, 524287(%r1,%r15)
0xe3 0x01 0xff 0xff 0x7f 0x85
# CHECK: lgat %r0, 524287(%r15,%r1)
0xe3 0x0f 0x1f 0xff 0x7f 0x85
# CHECK: lgat %r15, 0
0xe3 0xf0 0x00 0x00 0x00 0x85
# CHECK: lhi %r0, -32768
0xa7 0x08 0x80 0x00
@ -5653,6 +5713,36 @@
# CHECK: llgf %r15, 0
0xe3 0xf0 0x00 0x00 0x00 0x16
# CHECK: llgfat %r0, -524288
0xe3 0x00 0x00 0x00 0x80 0x9d
# CHECK: llgfat %r0, -1
0xe3 0x00 0x0f 0xff 0xff 0x9d
# CHECK: llgfat %r0, 0
0xe3 0x00 0x00 0x00 0x00 0x9d
# CHECK: llgfat %r0, 1
0xe3 0x00 0x00 0x01 0x00 0x9d
# CHECK: llgfat %r0, 524287
0xe3 0x00 0x0f 0xff 0x7f 0x9d
# CHECK: llgfat %r0, 0(%r1)
0xe3 0x00 0x10 0x00 0x00 0x9d
# CHECK: llgfat %r0, 0(%r15)
0xe3 0x00 0xf0 0x00 0x00 0x9d
# CHECK: llgfat %r0, 524287(%r1,%r15)
0xe3 0x01 0xff 0xff 0x7f 0x9d
# CHECK: llgfat %r0, 524287(%r15,%r1)
0xe3 0x0f 0x1f 0xff 0x7f 0x9d
# CHECK: llgfat %r15, 0
0xe3 0xf0 0x00 0x00 0x00 0x9d
# CHECK: llgtr %r0, %r15
0xb9 0x17 0x00 0x0f
@ -5692,6 +5782,36 @@
# CHECK: llgt %r15, 0
0xe3 0xf0 0x00 0x00 0x00 0x17
# CHECK: llgtat %r0, -524288
0xe3 0x00 0x00 0x00 0x80 0x9c
# CHECK: llgtat %r0, -1
0xe3 0x00 0x0f 0xff 0xff 0x9c
# CHECK: llgtat %r0, 0
0xe3 0x00 0x00 0x00 0x00 0x9c
# CHECK: llgtat %r0, 1
0xe3 0x00 0x00 0x01 0x00 0x9c
# CHECK: llgtat %r0, 524287
0xe3 0x00 0x0f 0xff 0x7f 0x9c
# CHECK: llgtat %r0, 0(%r1)
0xe3 0x00 0x10 0x00 0x00 0x9c
# CHECK: llgtat %r0, 0(%r15)
0xe3 0x00 0xf0 0x00 0x00 0x9c
# CHECK: llgtat %r0, 524287(%r1,%r15)
0xe3 0x01 0xff 0xff 0x7f 0x9c
# CHECK: llgtat %r0, 524287(%r15,%r1)
0xe3 0x0f 0x1f 0xff 0x7f 0x9c
# CHECK: llgtat %r15, 0
0xe3 0xf0 0x00 0x00 0x00 0x9c
# CHECK: llghr %r0, %r15
0xb9 0x85 0x00 0x0f
@ -6502,6 +6622,36 @@
# CHECK: l %r15, 0
0x58 0xf0 0x00 0x00
# CHECK: lat %r0, -524288
0xe3 0x00 0x00 0x00 0x80 0x9f
# CHECK: lat %r0, -1
0xe3 0x00 0x0f 0xff 0xff 0x9f
# CHECK: lat %r0, 0
0xe3 0x00 0x00 0x00 0x00 0x9f
# CHECK: lat %r0, 1
0xe3 0x00 0x00 0x01 0x00 0x9f
# CHECK: lat %r0, 524287
0xe3 0x00 0x0f 0xff 0x7f 0x9f
# CHECK: lat %r0, 0(%r1)
0xe3 0x00 0x10 0x00 0x00 0x9f
# CHECK: lat %r0, 0(%r15)
0xe3 0x00 0xf0 0x00 0x00 0x9f
# CHECK: lat %r0, 524287(%r1,%r15)
0xe3 0x01 0xff 0xff 0x7f 0x9f
# CHECK: lat %r0, 524287(%r15,%r1)
0xe3 0x0f 0x1f 0xff 0x7f 0x9f
# CHECK: lat %r15, 0
0xe3 0xf0 0x00 0x00 0x00 0x9f
# CHECK: lt %r0, -524288
0xe3 0x00 0x00 0x00 0x80 0x12

View File

@ -54,6 +54,46 @@
clgto %r0, 0
clgtno %r0, 0
#CHECK: error: invalid operand
#CHECK: lat %r0, -524289
#CHECK: error: invalid operand
#CHECK: lat %r0, 524288
lat %r0, -524289
lat %r0, 524288
#CHECK: error: invalid operand
#CHECK: lfhat %r0, -524289
#CHECK: error: invalid operand
#CHECK: lfhat %r0, 524288
lfhat %r0, -524289
lfhat %r0, 524288
#CHECK: error: invalid operand
#CHECK: lgat %r0, -524289
#CHECK: error: invalid operand
#CHECK: lgat %r0, 524288
lgat %r0, -524289
lgat %r0, 524288
#CHECK: error: invalid operand
#CHECK: llgfat %r0, -524289
#CHECK: error: invalid operand
#CHECK: llgfat %r0, 524288
llgfat %r0, -524289
llgfat %r0, 524288
#CHECK: error: invalid operand
#CHECK: llgtat %r0, -524289
#CHECK: error: invalid operand
#CHECK: llgtat %r0, 524288
llgtat %r0, -524289
llgtat %r0, 524288
#CHECK: error: instruction requires: vector
#CHECK: lcbb %r0, 0, 0

View File

@ -66,6 +66,116 @@
clgtnl %r0, 0(%r15)
clgtnh %r0, 0(%r15)
#CHECK: lat %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0x9f]
#CHECK: lat %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x9f]
#CHECK: lat %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0x9f]
#CHECK: lat %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0x9f]
#CHECK: lat %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0x9f]
#CHECK: lat %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0x9f]
#CHECK: lat %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0x9f]
#CHECK: lat %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0x9f]
#CHECK: lat %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0x9f]
#CHECK: lat %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0x9f]
lat %r0, -524288
lat %r0, -1
lat %r0, 0
lat %r0, 1
lat %r0, 524287
lat %r0, 0(%r1)
lat %r0, 0(%r15)
lat %r0, 524287(%r1,%r15)
lat %r0, 524287(%r15,%r1)
lat %r15, 0
#CHECK: lfhat %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0xc8]
#CHECK: lfhat %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0xc8]
#CHECK: lfhat %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0xc8]
#CHECK: lfhat %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0xc8]
#CHECK: lfhat %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0xc8]
#CHECK: lfhat %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0xc8]
#CHECK: lfhat %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0xc8]
#CHECK: lfhat %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0xc8]
#CHECK: lfhat %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0xc8]
#CHECK: lfhat %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0xc8]
lfhat %r0, -524288
lfhat %r0, -1
lfhat %r0, 0
lfhat %r0, 1
lfhat %r0, 524287
lfhat %r0, 0(%r1)
lfhat %r0, 0(%r15)
lfhat %r0, 524287(%r1,%r15)
lfhat %r0, 524287(%r15,%r1)
lfhat %r15, 0
#CHECK: lgat %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0x85]
#CHECK: lgat %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x85]
#CHECK: lgat %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0x85]
#CHECK: lgat %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0x85]
#CHECK: lgat %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0x85]
#CHECK: lgat %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0x85]
#CHECK: lgat %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0x85]
#CHECK: lgat %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0x85]
#CHECK: lgat %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0x85]
#CHECK: lgat %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0x85]
lgat %r0, -524288
lgat %r0, -1
lgat %r0, 0
lgat %r0, 1
lgat %r0, 524287
lgat %r0, 0(%r1)
lgat %r0, 0(%r15)
lgat %r0, 524287(%r1,%r15)
lgat %r0, 524287(%r15,%r1)
lgat %r15, 0
#CHECK: llgfat %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0x9d]
#CHECK: llgfat %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x9d]
#CHECK: llgfat %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0x9d]
#CHECK: llgfat %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0x9d]
#CHECK: llgfat %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0x9d]
#CHECK: llgfat %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0x9d]
#CHECK: llgfat %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0x9d]
#CHECK: llgfat %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0x9d]
#CHECK: llgfat %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0x9d]
#CHECK: llgfat %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0x9d]
llgfat %r0, -524288
llgfat %r0, -1
llgfat %r0, 0
llgfat %r0, 1
llgfat %r0, 524287
llgfat %r0, 0(%r1)
llgfat %r0, 0(%r15)
llgfat %r0, 524287(%r1,%r15)
llgfat %r0, 524287(%r15,%r1)
llgfat %r15, 0
#CHECK: llgtat %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0x9c]
#CHECK: llgtat %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x9c]
#CHECK: llgtat %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0x9c]
#CHECK: llgtat %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0x9c]
#CHECK: llgtat %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0x9c]
#CHECK: llgtat %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0x9c]
#CHECK: llgtat %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0x9c]
#CHECK: llgtat %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0x9c]
#CHECK: llgtat %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0x9c]
#CHECK: llgtat %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0x9c]
llgtat %r0, -524288
llgtat %r0, -1
llgtat %r0, 0
llgtat %r0, 1
llgtat %r0, 524287
llgtat %r0, 0(%r1)
llgtat %r0, 0(%r15)
llgtat %r0, 524287(%r1,%r15)
llgtat %r0, 524287(%r15,%r1)
llgtat %r15, 0
#CHECK: etnd %r0 # encoding: [0xb2,0xec,0x00,0x00]
#CHECK: etnd %r15 # encoding: [0xb2,0xec,0x00,0xf0]
#CHECK: etnd %r7 # encoding: [0xb2,0xec,0x00,0x70]