diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index a1c0c36ae54..7cbb4f715b5 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -814,6 +814,14 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { expandRXYPseudo(MI, SystemZ::LH, SystemZ::LHH); return true; + case SystemZ::LLCMux: + expandRXYPseudo(MI, SystemZ::LLC, SystemZ::LLCH); + return true; + + case SystemZ::LLHMux: + expandRXYPseudo(MI, SystemZ::LLH, SystemZ::LLHH); + return true; + case SystemZ::LMux: expandRXYPseudo(MI, SystemZ::L, SystemZ::LFH); return true; diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 6eeb91bffac..4b50747038b 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -456,9 +456,21 @@ let neverHasSideEffects = 1 in { def : Pat<(and GR64:$src, 0xffffffff), (LLGFR (EXTRACT_SUBREG GR64:$src, subreg_l32))>; -// 32-bit extensions from memory. -def LLC : UnaryRXY<"llc", 0xE394, azextloadi8, GR32, 1>; +// 32-bit extensions from 8-bit memory. LLCMux expands to LLC or LLCH, +// depending on the choice of register. +def LLCMux : UnaryRXYPseudo<"llc", azextloadi8, GRX32, 1>, + Requires<[FeatureHighWord]>; +def LLC : UnaryRXY<"llc", 0xE394, azextloadi8, GR32, 1>; +def LLCH : UnaryRXY<"llch", 0xE3C2, azextloadi8, GR32, 1>, + Requires<[FeatureHighWord]>; + +// 32-bit extensions from 16-bit memory. LLHMux expands to LLH or LLHH, +// depending on the choice of register. +def LLHMux : UnaryRXYPseudo<"llh", azextloadi16, GRX32, 2>, + Requires<[FeatureHighWord]>; def LLH : UnaryRXY<"llh", 0xE395, azextloadi16, GR32, 2>; +def LLHH : UnaryRXY<"llhh", 0xE3C6, azextloadi16, GR32, 2>, + Requires<[FeatureHighWord]>; def LLHRL : UnaryRILPC<"llhrl", 0xC42, aligned_azextloadi16, GR32>; // 64-bit extensions from memory. diff --git a/test/CodeGen/SystemZ/asm-18.ll b/test/CodeGen/SystemZ/asm-18.ll index ed285a0bfee..6eb0083f832 100644 --- a/test/CodeGen/SystemZ/asm-18.ll +++ b/test/CodeGen/SystemZ/asm-18.ll @@ -98,3 +98,51 @@ define void @f4(i16 *%ptr1, i16 *%ptr2) { "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) ret void } + +; Test zero-extending 8-bit loads into mixtures of high and low registers. +define void @f5(i8 *%ptr1, i8 *%ptr2) { +; CHECK-LABEL: f5: +; CHECK-DAG: llch [[REG1:%r[0-5]]], 0(%r2) +; CHECK-DAG: llc [[REG2:%r[0-5]]], 0(%r3) +; CHECK-DAG: llch [[REG3:%r[0-5]]], 4096(%r2) +; CHECK-DAG: llc [[REG4:%r[0-5]]], 524287(%r3) +; CHECK: blah [[REG1]], [[REG2]] +; CHECK: br %r14 + %ptr3 = getelementptr i8 *%ptr1, i64 4096 + %ptr4 = getelementptr i8 *%ptr2, i64 524287 + %val1 = load i8 *%ptr1 + %val2 = load i8 *%ptr2 + %val3 = load i8 *%ptr3 + %val4 = load i8 *%ptr4 + %ext1 = zext i8 %val1 to i32 + %ext2 = zext i8 %val2 to i32 + %ext3 = zext i8 %val3 to i32 + %ext4 = zext i8 %val4 to i32 + call void asm sideeffect "blah $0, $1, $2, $3", + "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) + ret void +} + +; Test zero-extending 16-bit loads into mixtures of high and low registers. +define void @f6(i16 *%ptr1, i16 *%ptr2) { +; CHECK-LABEL: f6: +; CHECK-DAG: llhh [[REG1:%r[0-5]]], 0(%r2) +; CHECK-DAG: llh [[REG2:%r[0-5]]], 0(%r3) +; CHECK-DAG: llhh [[REG3:%r[0-5]]], 4096(%r2) +; CHECK-DAG: llh [[REG4:%r[0-5]]], 524286(%r3) +; CHECK: blah [[REG1]], [[REG2]] +; CHECK: br %r14 + %ptr3 = getelementptr i16 *%ptr1, i64 2048 + %ptr4 = getelementptr i16 *%ptr2, i64 262143 + %val1 = load i16 *%ptr1 + %val2 = load i16 *%ptr2 + %val3 = load i16 *%ptr3 + %val4 = load i16 *%ptr4 + %ext1 = zext i16 %val1 to i32 + %ext2 = zext i16 %val2 to i32 + %ext3 = zext i16 %val3 to i32 + %ext4 = zext i16 %val4 to i32 + call void asm sideeffect "blah $0, $1, $2, $3", + "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) + ret void +} diff --git a/test/MC/Disassembler/SystemZ/insns.txt b/test/MC/Disassembler/SystemZ/insns.txt index 634ee873da4..4dd8c835613 100644 --- a/test/MC/Disassembler/SystemZ/insns.txt +++ b/test/MC/Disassembler/SystemZ/insns.txt @@ -3166,6 +3166,36 @@ # CHECK: llc %r15, 0 0xe3 0xf0 0x00 0x00 0x00 0x94 +# CHECK: llch %r0, -524288 +0xe3 0x00 0x00 0x00 0x80 0xc2 + +# CHECK: llch %r0, -1 +0xe3 0x00 0x0f 0xff 0xff 0xc2 + +# CHECK: llch %r0, 0 +0xe3 0x00 0x00 0x00 0x00 0xc2 + +# CHECK: llch %r0, 1 +0xe3 0x00 0x00 0x01 0x00 0xc2 + +# CHECK: llch %r0, 524287 +0xe3 0x00 0x0f 0xff 0x7f 0xc2 + +# CHECK: llch %r0, 0(%r1) +0xe3 0x00 0x10 0x00 0x00 0xc2 + +# CHECK: llch %r0, 0(%r15) +0xe3 0x00 0xf0 0x00 0x00 0xc2 + +# CHECK: llch %r0, 524287(%r1,%r15) +0xe3 0x01 0xff 0xff 0x7f 0xc2 + +# CHECK: llch %r0, 524287(%r15,%r1) +0xe3 0x0f 0x1f 0xff 0x7f 0xc2 + +# CHECK: llch %r15, 0 +0xe3 0xf0 0x00 0x00 0x00 0xc2 + # CHECK: llgcr %r0, %r15 0xb9 0x84 0x00 0x0f @@ -3322,6 +3352,36 @@ # CHECK: llh %r15, 0 0xe3 0xf0 0x00 0x00 0x00 0x95 +# CHECK: llhh %r0, -524288 +0xe3 0x00 0x00 0x00 0x80 0xc6 + +# CHECK: llhh %r0, -1 +0xe3 0x00 0x0f 0xff 0xff 0xc6 + +# CHECK: llhh %r0, 0 +0xe3 0x00 0x00 0x00 0x00 0xc6 + +# CHECK: llhh %r0, 1 +0xe3 0x00 0x00 0x01 0x00 0xc6 + +# CHECK: llhh %r0, 524287 +0xe3 0x00 0x0f 0xff 0x7f 0xc6 + +# CHECK: llhh %r0, 0(%r1) +0xe3 0x00 0x10 0x00 0x00 0xc6 + +# CHECK: llhh %r0, 0(%r15) +0xe3 0x00 0xf0 0x00 0x00 0xc6 + +# CHECK: llhh %r0, 524287(%r1,%r15) +0xe3 0x01 0xff 0xff 0x7f 0xc6 + +# CHECK: llhh %r0, 524287(%r15,%r1) +0xe3 0x0f 0x1f 0xff 0x7f 0xc6 + +# CHECK: llhh %r15, 0 +0xe3 0xf0 0x00 0x00 0x00 0xc6 + # CHECK: llihf %r0, 0 0xc0 0x0e 0x00 0x00 0x00 0x00 diff --git a/test/MC/SystemZ/insn-bad-z196.s b/test/MC/SystemZ/insn-bad-z196.s index 6214b8e277a..cf623bdbf2c 100644 --- a/test/MC/SystemZ/insn-bad-z196.s +++ b/test/MC/SystemZ/insn-bad-z196.s @@ -96,6 +96,22 @@ lhh %r0, -524289 lhh %r0, 524288 +#CHECK: error: invalid operand +#CHECK: llch %r0, -524289 +#CHECK: error: invalid operand +#CHECK: llch %r0, 524288 + + llch %r0, -524289 + llch %r0, 524288 + +#CHECK: error: invalid operand +#CHECK: llhh %r0, -524289 +#CHECK: error: invalid operand +#CHECK: llhh %r0, 524288 + + llhh %r0, -524289 + llhh %r0, 524288 + #CHECK: error: invalid operand #CHECK: loc %r0,0,-1 #CHECK: error: invalid operand diff --git a/test/MC/SystemZ/insn-bad.s b/test/MC/SystemZ/insn-bad.s index 8bfb134471a..3a46c48d7f8 100644 --- a/test/MC/SystemZ/insn-bad.s +++ b/test/MC/SystemZ/insn-bad.s @@ -1611,6 +1611,11 @@ llc %r0, -524289 llc %r0, 524288 +#CHECK: error: {{(instruction requires: high-word)?}} +#CHECK: llch %r0, 0 + + llch %r0, 0 + #CHECK: error: invalid operand #CHECK: llgc %r0, -524289 #CHECK: error: invalid operand @@ -1671,6 +1676,11 @@ llh %r0, -524289 llh %r0, 524288 +#CHECK: error: {{(instruction requires: high-word)?}} +#CHECK: llhh %r0, 0 + + llhh %r0, 0 + #CHECK: error: offset out of range #CHECK: llhrl %r0, -0x1000000002 #CHECK: error: offset out of range diff --git a/test/MC/SystemZ/insn-good-z196.s b/test/MC/SystemZ/insn-good-z196.s index fa4471e598d..ca8832930e1 100644 --- a/test/MC/SystemZ/insn-good-z196.s +++ b/test/MC/SystemZ/insn-good-z196.s @@ -229,6 +229,50 @@ lhh %r0, 524287(%r15,%r1) lhh %r15, 0 +#CHECK: llch %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0xc2] +#CHECK: llch %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0xc2] +#CHECK: llch %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0xc2] +#CHECK: llch %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0xc2] +#CHECK: llch %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0xc2] +#CHECK: llch %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0xc2] +#CHECK: llch %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0xc2] +#CHECK: llch %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0xc2] +#CHECK: llch %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0xc2] +#CHECK: llch %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0xc2] + + llch %r0, -524288 + llch %r0, -1 + llch %r0, 0 + llch %r0, 1 + llch %r0, 524287 + llch %r0, 0(%r1) + llch %r0, 0(%r15) + llch %r0, 524287(%r1,%r15) + llch %r0, 524287(%r15,%r1) + llch %r15, 0 + +#CHECK: llhh %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0xc6] +#CHECK: llhh %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0xc6] +#CHECK: llhh %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0xc6] +#CHECK: llhh %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0xc6] +#CHECK: llhh %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0xc6] +#CHECK: llhh %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0xc6] +#CHECK: llhh %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0xc6] +#CHECK: llhh %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0xc6] +#CHECK: llhh %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0xc6] +#CHECK: llhh %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0xc6] + + llhh %r0, -524288 + llhh %r0, -1 + llhh %r0, 0 + llhh %r0, 1 + llhh %r0, 524287 + llhh %r0, 0(%r1) + llhh %r0, 0(%r15) + llhh %r0, 524287(%r1,%r15) + llhh %r0, 524287(%r15,%r1) + llhh %r15, 0 + #CHECK: loc %r0, 0, 0 # encoding: [0xeb,0x00,0x00,0x00,0x00,0xf2] #CHECK: loc %r0, 0, 15 # encoding: [0xeb,0x0f,0x00,0x00,0x00,0xf2] #CHECK: loc %r0, -524288, 0 # encoding: [0xeb,0x00,0x00,0x00,0x80,0xf2]