Commit 005e3e05 by Kazu Hirata Committed by Kazu Hirata

* config/h8300/h8300.c: Revise comments about shift code.

From-SVN: r49030
parent 64bead4c
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>
......
......@@ -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
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment