diff options
author | Richard Henderson <rth@cygnus.com> | 1999-04-13 16:19:26 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1999-04-13 17:19:26 -0600 |
commit | fb693d4449e4997e2e26549313ef6115bc41d629 (patch) | |
tree | 7b18d5275c0d4fdd99ef657513638bbaef61e3ef /gcc | |
parent | a8b7e1861e18c1234e6ae99c250e244492ab7a1a (diff) | |
download | gcc-fb693d4449e4997e2e26549313ef6115bc41d629.zip gcc-fb693d4449e4997e2e26549313ef6115bc41d629.tar.gz gcc-fb693d4449e4997e2e26549313ef6115bc41d629.tar.bz2 |
i386.c (memory_address_length): New function.
* i386.c (memory_address_length): New function.
* i386.h (memory_address_length): Declare it.
From-SVN: r26432
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 117 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 1 |
3 files changed, 123 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b9fe80a..f1c5773 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Wed Apr 14 00:08:46 1999 Richard Henderson <rth@cygnus.com> + + * i386.c (memory_address_length): New function. + * i386.h (memory_address_length): Declare it. + Tue Apr 13 22:52:04 1999 Donn Terry (donn@interix.com) Martin Heller (Ing.-Buero_Heller@t-online.de) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e6f807b..671d529 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5545,3 +5545,120 @@ output_ashlsi3 (operands) /* Otherwise use a shift instruction. */ return AS2 (sal%L0,%2,%0); } + +/* Calculate the length of the memory address in the instruction + encoding. Does not include the one-byte modrm, opcode, or prefix. */ + +int +memory_address_length (addr) + rtx addr; +{ + rtx base, index, disp, scale; + rtx op0, op1; + int len; + + if (GET_CODE (addr) == PRE_DEC + || GET_CODE (addr) == POST_INC) + return 0; + + /* Register Indirect. */ + if (register_operand (addr, Pmode)) + { + /* Special cases: ebp and esp need the two-byte modrm form. + + We change [ESI] to [ESI+0] on the K6 when not optimizing + for size. */ + if (addr == stack_pointer_rtx + || addr == arg_pointer_rtx + || addr == frame_pointer_rtx + || (REGNO_REG_CLASS (REGNO (addr)) == SIREG + && ix86_cpu == PROCESSOR_K6 && !optimize_size) + return 1; + else + return 0; + } + + /* Direct Addressing. */ + if (CONSTANT_P (addr)) + return 4; + + index = base = disp = scale = NULL_RTX; + op0 = XEXP (addr, 0); + op1 = XEXP (addr, 1); + + if (GET_CODE (addr) == PLUS) + { + if (register_operand (op0, Pmode)) + { + if (register_operand (op1, Pmode)) + index = op0, base = op1; + else + base = op0, disp = op1; + } + else if (GET_CODE (op0) == MULT) + { + index = XEXP (op0, 0); + scale = XEXP (op0, 1); + if (register_operand (op1, Pmode)) + base = op1; + else + disp = op1; + } + else if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == MULT) + { + index = XEXP (XEXP (op0, 0), 0); + scale = XEXP (XEXP (op0, 0), 1); + base = XEXP (op0, 1); + disp = op1; + } + else if (GET_CODE (op0) == PLUS) + { + index = XEXP (op0, 0); + base = XEXP (op0, 1); + disp = op1; + } + else + abort (); + } + else if (GET_CODE (addr) == MULT + /* We're called for lea too, which implements ashift on occasion. */ + || GET_CODE (addr) == ASHIFT) + { + index = XEXP (addr, 0); + scale = XEXP (addr, 1); + } + else + abort (); + + /* Allow arg pointer and stack pointer as index if there is not scaling */ + if (base && index && !scale + && (index == stack_pointer_rtx + || index == arg_pointer_rtx + || index == frame_pointer_rtx)) + { + rtx tmp = base; + base = index; + index = tmp; + } + + /* Special case: ebp cannot be encoded as a base without a displacement. */ + if (base == frame_pointer_rtx && !disp) + disp = const0_rtx; + + /* Find the length of the displacement constant. */ + len = 0; + if (disp) + { + if (GET_CODE (disp) == CONST_INT + && CONST_OK_FOR_LETTER_P (INTVAL (disp), 'K')) + len = 1; + else + len = 4; + } + + /* An index requires the two-byte modrm form. */ + if (index) + len += 1; + + return len; +} diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 3e6ed9e..de4da2c 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2765,6 +2765,7 @@ extern char *output_fp_conditional_move (); extern int ix86_can_use_return_insn_p (); extern int small_shift_operand (); extern char *output_ashlsi3 (); +extern int memory_address_length (); #ifdef NOTYET extern struct rtx_def *copy_all_rtx (); |