From 9813dbf396e63f6d4fd99fe0f6651e831cb7414b Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 1 Oct 2013 12:22:49 +0000 Subject: [PATCH] [SystemZ] Add truncating high-word stores (STCH and STHH) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191743 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SystemZ/SystemZInstrInfo.cpp | 8 ++++ lib/Target/SystemZ/SystemZInstrInfo.td | 20 +++++++-- test/CodeGen/SystemZ/asm-18.ll | 46 +++++++++++++++++++ test/MC/Disassembler/SystemZ/insns.txt | 60 +++++++++++++++++++++++++ test/MC/SystemZ/insn-bad-z196.s | 16 +++++++ test/MC/SystemZ/insn-bad.s | 10 +++++ test/MC/SystemZ/insn-good-z196.s | 44 ++++++++++++++++++ 7 files changed, 200 insertions(+), 4 deletions(-) diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 7cbb4f715b5..199299379cf 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -826,6 +826,14 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { expandRXYPseudo(MI, SystemZ::L, SystemZ::LFH); return true; + case SystemZ::STCMux: + expandRXYPseudo(MI, SystemZ::STC, SystemZ::STCH); + return true; + + case SystemZ::STHMux: + expandRXYPseudo(MI, SystemZ::STH, SystemZ::STHH); + return true; + case SystemZ::STMux: expandRXYPseudo(MI, SystemZ::ST, SystemZ::STFH); return true; diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 4b50747038b..ea1fb8e38f6 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -488,10 +488,22 @@ def LLGFRL : UnaryRILPC<"llgfrl", 0xC4E, aligned_azextloadi32, GR64>; def : Pat<(i32 (trunc GR64:$src)), (EXTRACT_SUBREG GR64:$src, subreg_l32)>; -// Truncations of 32-bit registers to memory. -defm STC : StoreRXPair<"stc", 0x42, 0xE372, truncstorei8, GR32, 1>; -defm STH : StoreRXPair<"sth", 0x40, 0xE370, truncstorei16, GR32, 2>; -def STHRL : StoreRILPC<"sthrl", 0xC47, aligned_truncstorei16, GR32>; +// Truncations of 32-bit registers to 8-bit memory. STCMux expands to +// STC, STCY or STCH, depending on the choice of register. +def STCMux : StoreRXYPseudo, + Requires<[FeatureHighWord]>; +defm STC : StoreRXPair<"stc", 0x42, 0xE372, truncstorei8, GR32, 1>; +def STCH : StoreRXY<"stch", 0xE3C3, truncstorei8, GRH32, 1>, + Requires<[FeatureHighWord]>; + +// Truncations of 32-bit registers to 16-bit memory. STHMux expands to +// STH, STHY or STHH, depending on the choice of register. +def STHMux : StoreRXYPseudo, + Requires<[FeatureHighWord]>; +defm STH : StoreRXPair<"sth", 0x40, 0xE370, truncstorei16, GR32, 2>; +def STHH : StoreRXY<"sthh", 0xE3C7, truncstorei16, GRH32, 2>, + Requires<[FeatureHighWord]>; +def STHRL : StoreRILPC<"sthrl", 0xC47, aligned_truncstorei16, GR32>; // Truncations of 64-bit registers to memory. defm : StoreGR64Pair; diff --git a/test/CodeGen/SystemZ/asm-18.ll b/test/CodeGen/SystemZ/asm-18.ll index 6eb0083f832..df2c920232f 100644 --- a/test/CodeGen/SystemZ/asm-18.ll +++ b/test/CodeGen/SystemZ/asm-18.ll @@ -146,3 +146,49 @@ define void @f6(i16 *%ptr1, i16 *%ptr2) { "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) ret void } + +; Test truncating stores of high and low registers into 8-bit memory. +define void @f7(i8 *%ptr1, i8 *%ptr2) { +; CHECK-LABEL: f7: +; CHECK: blah [[REG1:%r[0-5]]], [[REG2:%r[0-5]]] +; CHECK-DAG: stch [[REG1]], 0(%r2) +; CHECK-DAG: stc [[REG2]], 0(%r3) +; CHECK-DAG: stch [[REG1]], 4096(%r2) +; CHECK-DAG: stcy [[REG2]], 524287(%r3) +; CHECK: br %r14 + %res = call { i32, i32 } asm "blah $0, $1", "=h,=r"() + %res1 = extractvalue { i32, i32 } %res, 0 + %res2 = extractvalue { i32, i32 } %res, 1 + %trunc1 = trunc i32 %res1 to i8 + %trunc2 = trunc i32 %res2 to i8 + %ptr3 = getelementptr i8 *%ptr1, i64 4096 + %ptr4 = getelementptr i8 *%ptr2, i64 524287 + store i8 %trunc1, i8 *%ptr1 + store i8 %trunc2, i8 *%ptr2 + store i8 %trunc1, i8 *%ptr3 + store i8 %trunc2, i8 *%ptr4 + ret void +} + +; Test truncating stores of high and low registers into 16-bit memory. +define void @f8(i16 *%ptr1, i16 *%ptr2) { +; CHECK-LABEL: f8: +; CHECK: blah [[REG1:%r[0-5]]], [[REG2:%r[0-5]]] +; CHECK-DAG: sthh [[REG1]], 0(%r2) +; CHECK-DAG: sth [[REG2]], 0(%r3) +; CHECK-DAG: sthh [[REG1]], 4096(%r2) +; CHECK-DAG: sthy [[REG2]], 524286(%r3) +; CHECK: br %r14 + %res = call { i32, i32 } asm "blah $0, $1", "=h,=r"() + %res1 = extractvalue { i32, i32 } %res, 0 + %res2 = extractvalue { i32, i32 } %res, 1 + %trunc1 = trunc i32 %res1 to i16 + %trunc2 = trunc i32 %res2 to i16 + %ptr3 = getelementptr i16 *%ptr1, i64 2048 + %ptr4 = getelementptr i16 *%ptr2, i64 262143 + store i16 %trunc1, i16 *%ptr1 + store i16 %trunc2, i16 *%ptr2 + store i16 %trunc1, i16 *%ptr3 + store i16 %trunc2, i16 *%ptr4 + ret void +} diff --git a/test/MC/Disassembler/SystemZ/insns.txt b/test/MC/Disassembler/SystemZ/insns.txt index 4dd8c835613..4775a5d3121 100644 --- a/test/MC/Disassembler/SystemZ/insns.txt +++ b/test/MC/Disassembler/SystemZ/insns.txt @@ -6664,6 +6664,36 @@ # CHECK: stc %r15, 0 0x42 0xf0 0x00 0x00 +# CHECK: stch %r0, -524288 +0xe3 0x00 0x00 0x00 0x80 0xc3 + +# CHECK: stch %r0, -1 +0xe3 0x00 0x0f 0xff 0xff 0xc3 + +# CHECK: stch %r0, 0 +0xe3 0x00 0x00 0x00 0x00 0xc3 + +# CHECK: stch %r0, 1 +0xe3 0x00 0x00 0x01 0x00 0xc3 + +# CHECK: stch %r0, 524287 +0xe3 0x00 0x0f 0xff 0x7f 0xc3 + +# CHECK: stch %r0, 0(%r1) +0xe3 0x00 0x10 0x00 0x00 0xc3 + +# CHECK: stch %r0, 0(%r15) +0xe3 0x00 0xf0 0x00 0x00 0xc3 + +# CHECK: stch %r0, 524287(%r1,%r15) +0xe3 0x01 0xff 0xff 0x7f 0xc3 + +# CHECK: stch %r0, 524287(%r15,%r1) +0xe3 0x0f 0x1f 0xff 0x7f 0xc3 + +# CHECK: stch %r15, 0 +0xe3 0xf0 0x00 0x00 0x00 0xc3 + # CHECK: stcy %r0, -524288 0xe3 0x00 0x00 0x00 0x80 0x72 @@ -6847,6 +6877,36 @@ # CHECK: sth %r15, 0 0x40 0xf0 0x00 0x00 +# CHECK: sthh %r0, -524288 +0xe3 0x00 0x00 0x00 0x80 0xc7 + +# CHECK: sthh %r0, -1 +0xe3 0x00 0x0f 0xff 0xff 0xc7 + +# CHECK: sthh %r0, 0 +0xe3 0x00 0x00 0x00 0x00 0xc7 + +# CHECK: sthh %r0, 1 +0xe3 0x00 0x00 0x01 0x00 0xc7 + +# CHECK: sthh %r0, 524287 +0xe3 0x00 0x0f 0xff 0x7f 0xc7 + +# CHECK: sthh %r0, 0(%r1) +0xe3 0x00 0x10 0x00 0x00 0xc7 + +# CHECK: sthh %r0, 0(%r15) +0xe3 0x00 0xf0 0x00 0x00 0xc7 + +# CHECK: sthh %r0, 524287(%r1,%r15) +0xe3 0x01 0xff 0xff 0x7f 0xc7 + +# CHECK: sthh %r0, 524287(%r15,%r1) +0xe3 0x0f 0x1f 0xff 0x7f 0xc7 + +# CHECK: sthh %r15, 0 +0xe3 0xf0 0x00 0x00 0x00 0xc7 + # CHECK: stfh %r0, -524288 0xe3 0x00 0x00 0x00 0x80 0xcb diff --git a/test/MC/SystemZ/insn-bad-z196.s b/test/MC/SystemZ/insn-bad-z196.s index cf623bdbf2c..0ed33702e48 100644 --- a/test/MC/SystemZ/insn-bad-z196.s +++ b/test/MC/SystemZ/insn-bad-z196.s @@ -244,6 +244,22 @@ srlk %r0,%r0,0(%r0) srlk %r0,%r0,0(%r1,%r2) +#CHECK: error: invalid operand +#CHECK: stch %r0, -524289 +#CHECK: error: invalid operand +#CHECK: stch %r0, 524288 + + stch %r0, -524289 + stch %r0, 524288 + +#CHECK: error: invalid operand +#CHECK: sthh %r0, -524289 +#CHECK: error: invalid operand +#CHECK: sthh %r0, 524288 + + sthh %r0, -524289 + sthh %r0, 524288 + #CHECK: error: invalid operand #CHECK: stfh %r0, -524289 #CHECK: error: invalid operand diff --git a/test/MC/SystemZ/insn-bad.s b/test/MC/SystemZ/insn-bad.s index 3a46c48d7f8..3fe3f4d6a7b 100644 --- a/test/MC/SystemZ/insn-bad.s +++ b/test/MC/SystemZ/insn-bad.s @@ -2915,6 +2915,11 @@ stc %r0, -1 stc %r0, 4096 +#CHECK: error: {{(instruction requires: high-word)?}} +#CHECK: stch %r0, 0 + + stch %r0, 0 + #CHECK: error: invalid operand #CHECK: stcy %r0, -524289 #CHECK: error: invalid operand @@ -2985,6 +2990,11 @@ sth %r0, -1 sth %r0, 4096 +#CHECK: error: {{(instruction requires: high-word)?}} +#CHECK: sthh %r0, 0 + + sthh %r0, 0 + #CHECK: error: offset out of range #CHECK: sthrl %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 ca8832930e1..769ab02ee4b 100644 --- a/test/MC/SystemZ/insn-good-z196.s +++ b/test/MC/SystemZ/insn-good-z196.s @@ -647,6 +647,50 @@ srlk %r0,%r0,524287(%r1) srlk %r0,%r0,524287(%r15) +#CHECK: stch %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0xc3] +#CHECK: stch %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0xc3] +#CHECK: stch %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0xc3] +#CHECK: stch %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0xc3] +#CHECK: stch %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0xc3] +#CHECK: stch %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0xc3] +#CHECK: stch %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0xc3] +#CHECK: stch %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0xc3] +#CHECK: stch %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0xc3] +#CHECK: stch %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0xc3] + + stch %r0, -524288 + stch %r0, -1 + stch %r0, 0 + stch %r0, 1 + stch %r0, 524287 + stch %r0, 0(%r1) + stch %r0, 0(%r15) + stch %r0, 524287(%r1,%r15) + stch %r0, 524287(%r15,%r1) + stch %r15, 0 + +#CHECK: sthh %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0xc7] +#CHECK: sthh %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0xc7] +#CHECK: sthh %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0xc7] +#CHECK: sthh %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0xc7] +#CHECK: sthh %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0xc7] +#CHECK: sthh %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0xc7] +#CHECK: sthh %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0xc7] +#CHECK: sthh %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0xc7] +#CHECK: sthh %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0xc7] +#CHECK: sthh %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0xc7] + + sthh %r0, -524288 + sthh %r0, -1 + sthh %r0, 0 + sthh %r0, 1 + sthh %r0, 524287 + sthh %r0, 0(%r1) + sthh %r0, 0(%r15) + sthh %r0, 524287(%r1,%r15) + sthh %r0, 524287(%r15,%r1) + sthh %r15, 0 + #CHECK: stfh %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0xcb] #CHECK: stfh %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0xcb] #CHECK: stfh %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0xcb] -- 2.34.1