diff options
author | Kazu Hirata <kazu@hxi.com> | 2002-01-21 02:04:46 +0000 |
---|---|---|
committer | Kazu Hirata <kazu@gcc.gnu.org> | 2002-01-21 02:04:46 +0000 |
commit | 005e3e053fb770c9a471c22f4dba447b532fe701 (patch) | |
tree | 3659b41045c5445978227c7e053d188fc2a22375 /gcc | |
parent | 64bead4cff14afc6ef91fa29870abeb649d5b47b (diff) | |
download | gcc-005e3e053fb770c9a471c22f4dba447b532fe701.zip gcc-005e3e053fb770c9a471c22f4dba447b532fe701.tar.gz gcc-005e3e053fb770c9a471c22f4dba447b532fe701.tar.bz2 |
* config/h8300/h8300.c: Revise comments about shift code.
From-SVN: r49030
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.c | 137 |
2 files changed, 43 insertions, 98 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 466ea85..05441a9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2002-01-20 Kazu Hirata <kazu@hxi.com> + * config/h8300/h8300.c: Revise comments about shift code. + +2002-01-20 Kazu Hirata <kazu@hxi.com> + * config/h8300/h8300.c (function_arg): Update a comment. 2002-01-20 Kazu Hirata <kazu@hxi.com> diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 890d7e5..db12b64 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -1669,53 +1669,42 @@ output_logical_op (mode, code, operands) /* Shifts. - We devote a fair bit of code to getting efficient shifts since we can only - shift one bit at a time on the H8/300 and H8/300H and only one or two - bits at a time on the H8/S. - - The basic shift methods: - - * loop shifts -- emit a loop using one (or two on H8/S) bit shifts; - this is the default. SHIFT_LOOP - - * inlined shifts -- emit straight line code for the shift; this is - used when a straight line shift is about the same size or smaller - than a loop. We allow the inline version to be slightly longer in - some cases as it saves a register. SHIFT_INLINE - - * rotate + and -- rotate the value the opposite direction, then - mask off the values we don't need. This is used when only a few - of the bits in the original value will survive in the shifted value. - Again, this is used when it's about the same size or smaller than - a loop. We allow this version to be slightly longer as it is usually - much faster than a loop. SHIFT_ROT_AND - - * swap (+ shifts) -- often it's possible to swap bytes/words to - simulate a shift by 8/16. Once swapped a few inline shifts can be - added if the shift count is slightly more than 8 or 16. This is used - when it's about the same size or smaller than a loop. We allow this - version to be slightly longer as it is usually much faster than a loop. - SHIFT_SPECIAL - - * There other oddballs. Not worth explaining. SHIFT_SPECIAL - - Here are some thoughts on what the absolutely positively best code is. - "Best" here means some rational trade-off between code size and speed, - where speed is more preferred but not at the expense of generating 20 insns. - - A trailing '*' after the shift count indicates the "best" mode isn't - implemented. + We devote a fair bit of code to getting efficient shifts since we + can only shift one bit at a time on the H8/300 and H8/300H and only + one or two bits at a time on the H8/S. + + All shift code falls into one of the following ways of + implementation: + + o SHIFT_INLINE: Emit straight line code for the shift; this is used + when a straight line shift is about the same size or smaller than + a loop. + + o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask + off the bits we don't need. This is used when only a few of the + bits in the original value will survive in the shifted value. + + o SHIFT_SPECIAL: Often it's possible to move a byte or a word to + simulate a shift by 8, 16, or 24 bits. Once moved, a few inline + shifts can be added if the shift count is slightly more than 8 or + 16. This case also includes other oddballs that are not worth + explaning here. + + o SHIFT_LOOP: Emit a loop using one (or two on H8/S) bit shifts. + + Here are some thoughts on what the absolutely positively best code + is. "Best" here means some rational trade-off between code size + and speed, where speed is more preferred but not at the expense of + generating 20 insns. + + Below, a trailing '*' after the shift count indicates the "best" + mode isn't implemented. We only describe SHIFT_SPECIAL cases to + simplify the table. For other cases, refer to shift_alg_[qhs]i. H8/300 QImode shifts - 1-4 - do them inline - 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits - ASHIFTRT: loop - 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits - ASHIFTRT: shll, subx (propagate carry bit to all bits) + 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits) H8/300 HImode shifts - 1-4 - do them inline - 5-6 - loop 7 - shift 2nd half other way into carry. copy 1st half into 2nd half rotate 2nd half other way with carry @@ -1724,40 +1713,21 @@ output_logical_op (mode, code, operands) sign extend 1st half (ASHIFTRT) 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT) 9-12 - do shift by 8, inline remaining shifts - 13-14* - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0 - - ASHIFTRT: loop - 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0 - - ASHIFTRT: shll, subx, set other byte + 15 - ASHIFTRT: shll, subx, set other byte H8/300 SImode shifts - 1-2 - do them inline - 3-6 - loop 7* - shift other way once, move bytes into place, move carry into place (possibly with sign extension) 8 - move bytes into place, zero or sign extend other - 9-14 - loop 15* - shift other way once, move word into place, move carry into place 16 - move word, zero or sign extend other - 17-23 - loop 24* - move bytes into place, zero or sign extend other - 25-27 - loop - 28-30* - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place, - zero others - ASHIFTRT: loop - 31 - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place, - zero others - ASHIFTRT: shll top byte, subx, copy to other bytes + 31 - ASHIFTRT: shll top byte, subx, copy to other bytes H8/300H QImode shifts (same as H8/300 QImode shifts) - 1-4 - do them inline - 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits - ASHIFTRT: loop - 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits - ASHIFTRT: shll, subx (propagate carry bit to all bits) + 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits) H8/300H HImode shifts - 1-4 - do them inline - 5-6 - loop 7 - shift 2nd half other way into carry. copy 1st half into 2nd half rotate entire word other way using carry @@ -1765,22 +1735,16 @@ output_logical_op (mode, code, operands) sign extend remaining bits (ASHIFTRT) 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT) 9-12 - do shift by 8, inline remaining shifts - 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0 - - ASHIFTRT: loop - 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0 - - ASHIFTRT: shll, subx, set other byte + 15 - ASHIFTRT: shll, subx, set other byte H8/300H SImode shifts (These are complicated by the fact that we don't have byte level access to the top word.) A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw) - 1-4 - do them inline - 5-14 - loop 15* - shift other way once, move word into place, move carry into place (with sign extension for ASHIFTRT) 16 - move word into place, zero or sign extend other 17-20 - do 16bit shift, then inline remaining shifts - 20-23 - loop 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0, move word 0 to word 1, zero word 0 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0, @@ -1789,36 +1753,24 @@ output_logical_op (mode, code, operands) sign extend byte 0, sign extend word 0 25-27* - either loop, or do 24 bit shift, inline rest - 28-30 - ASHIFT: rotate 4/3/2, mask - LSHIFTRT: rotate 4/3/2, mask - ASHIFTRT: loop 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0 H8/S QImode shifts - 1-6 - do them inline - 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits - ASHIFTRT: shll, subx (propagate carry bit to all bits) + 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits) H8/S HImode shifts - 1-7 - do them inline 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT) 9-12 - do shift by 8, inline remaining shifts - 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0 - - ASHIFTRT: loop - 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0 - - ASHIFTRT: shll, subx, set other byte + 15 - ASHIFTRT: shll, subx, set other byte H8/S SImode shifts (These are complicated by the fact that we don't have byte level access to the top word.) A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw) - 1-10 - do them inline - 11-14 - loop 15* - shift other way once, move word into place, move carry into place (with sign extension for ASHIFTRT) 16 - move word into place, zero or sign extend other 17-20 - do 16bit shift, then inline remaining shifts - 21-23 - loop 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0, move word 0 to word 1, zero word 0 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0, @@ -1827,9 +1779,6 @@ output_logical_op (mode, code, operands) sign extend byte 0, sign extend word 0 25-27* - either loop, or do 24 bit shift, inline rest - 28-30 - ASHIFT: rotate 4/3/2, mask - LSHIFTRT: rotate 4/3/2, mask - ASHIFTRT: loop 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0 Panic!!! */ @@ -1878,15 +1827,7 @@ expand_a_shift (mode, code, operands) return 1; } -/* Shift algorithm determination. - - There are various ways of doing a shift: - SHIFT_INLINE: If the amount is small enough, just generate as many one-bit - shifts as we need. - SHIFT_ROT_AND: If the amount is large but close to either end, rotate the - necessary bits into position and then set the rest to zero. - SHIFT_SPECIAL: Hand crafted assembler. - SHIFT_LOOP: If the above methods fail, just loop. */ +/* See above for explanation of this enum. */ enum shift_alg { |