diff options
author | Adrian Straetling <straetling@de.ibm.com> | 2005-10-19 16:37:10 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2005-10-19 16:37:10 +0000 |
commit | 6fa05db65c8202c23d3370feb72fc41472498e82 (patch) | |
tree | 077e1a0a0ddd7137851ee644b623a485c87fa8a9 /gcc/config/s390/s390.c | |
parent | a1b23b2f7cef7cd0b8df65ed1936b8ea7ea65696 (diff) | |
download | gcc-6fa05db65c8202c23d3370feb72fc41472498e82.zip gcc-6fa05db65c8202c23d3370feb72fc41472498e82.tar.gz gcc-6fa05db65c8202c23d3370feb72fc41472498e82.tar.bz2 |
s390.c (s390_expand_insv): New.
2005-10-19 Adrian Straetling <straetling@de.ibm.com>
* config/s390/s390.c (s390_expand_insv): New.
* config/s390/s390-protos.h (s390_expand_insv): Declare.
* config/s390/s390.md ("UNSPEC_SETHIGH"): Rename to "UNSPEC_ICM".
("icm_hi"): Remove mode attribute.
("*sethigh<mode><mode>"): Rewrite to "sethighpart<mode>".
Adjust all uses.
("*extracthi", "*extractqi"): Remove.
(extv<mode>", "*extzv<mode>"): New.
("insv", "*insv<mode>_mem_reg", "*insvdi_mem_reghigh",
"*insv<mode>_reg_imm", "*insv<mode>_reg_extimm"): New.
From-SVN: r105625
Diffstat (limited to 'gcc/config/s390/s390.c')
-rw-r--r-- | gcc/config/s390/s390.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 445f4e1..009c178 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -3815,6 +3815,101 @@ s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1, return false; } +/* Expand code for the insv template. Return true if successful, false else. */ + +bool +s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) +{ + int bitsize = INTVAL (op1); + int bitpos = INTVAL (op2); + + /* We need byte alignement. */ + if (bitsize % BITS_PER_UNIT) + return false; + + if (bitpos == 0 + && memory_operand (dest, VOIDmode) + && (register_operand (src, word_mode) + || const_int_operand (src, VOIDmode))) + { + /* Emit standard pattern if possible. */ + enum machine_mode mode = smallest_mode_for_size (bitsize, MODE_INT); + if (GET_MODE_BITSIZE (mode) == bitsize) + emit_move_insn (adjust_address (dest, mode, 0), gen_lowpart (mode, src)); + + /* (set (ze (mem)) (const_int)). */ + else if (const_int_operand (src, VOIDmode)) + { + int size = bitsize / BITS_PER_UNIT; + rtx src_mem = adjust_address (force_const_mem (word_mode, src), BLKmode, + GET_MODE_SIZE (word_mode) - size); + + dest = adjust_address (dest, BLKmode, 0); + set_mem_size (dest, GEN_INT (size)); + s390_expand_movmem (dest, src_mem, GEN_INT (size)); + } + + /* (set (ze (mem)) (reg)). */ + else if (register_operand (src, word_mode)) + { + if (bitsize <= GET_MODE_BITSIZE (SImode)) + emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, op1, + const0_rtx), src); + else + { + /* Emit st,stcmh sequence. */ + int stcmh_width = bitsize - GET_MODE_BITSIZE (SImode); + int size = stcmh_width / BITS_PER_UNIT; + + emit_move_insn (adjust_address (dest, SImode, size), + gen_lowpart (SImode, src)); + set_mem_size (dest, GEN_INT (size)); + emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, GEN_INT + (stcmh_width), const0_rtx), + gen_rtx_LSHIFTRT (word_mode, src, GEN_INT + (GET_MODE_BITSIZE (SImode)))); + } + } + else + return false; + + return true; + } + + /* (set (ze (reg)) (const_int)). */ + if (TARGET_ZARCH + && register_operand (dest, word_mode) + && (bitpos % 16) == 0 + && (bitsize % 16) == 0 + && const_int_operand (src, VOIDmode)) + { + HOST_WIDE_INT val = INTVAL (src); + int regpos = bitpos + bitsize; + + while (regpos > bitpos) + { + enum machine_mode putmode; + int putsize; + + if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32)) + putmode = SImode; + else + putmode = HImode; + + putsize = GET_MODE_BITSIZE (putmode); + regpos -= putsize; + emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, + GEN_INT (putsize), + GEN_INT (regpos)), + gen_int_mode (val, putmode)); + val >>= putsize; + } + gcc_assert (regpos == bitpos); + return true; + } + + return false; +} /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL. We need to emit DTP-relative relocations. */ |