Message ID | 4ECF7DC0.9080101@gjlay.de |
---|---|
State | New |
Headers | show |
2011/11/25 Georg-Johann Lay <avr@gjlay.de> > > Georg-Johann Lay wrote: > > Denis Chertykov wrote: > >> 2011/11/20 Georg-Johann Lay <.....>: > >>> Subtracting 0x20 to get the SFR address from a RAM address is scattered all > >>> over the backend. The patch makes - PRINT_OPERAND_PUNCT_VALID_P and uses %- to > >>> subtract the SFR offset instead of hard coded magic number 0x20 all over the > >>> place. The offset is stored in a new field base_arch_s.sfr_offset > >> I don't like '%-' as a sequence and I don't like it as a suffix. > >> May be a right way is an adding a new prefix '%i' or '%I'. > >> I.e. > >> %m0 - memory address > >> %i0 - io address (equal to %m0 - 0x20) > >> > >> Denis. > > > > hmmm. The intention was to be able to specify SFR offset in inline assembly, > > for example. The offset is independent of operands; it is a specific to the > > architecture. > > > > Anyway, here is a updated patch. Its the same as the last except that it > > implements %i instead of %- and avr_out_plus_1 prints constants more > > eye-friendly. And there was a missing return close to the end of out_movqi_mr_r. > > > > Passes test suite. > > > > Ok? > > > > Johann > > > > * config/avr/avr.h (struct base_arch_s): Add field sfr_offset. > > * config/avr/avr-devices.c: Ditto. And initialize it. > > * config/avr/avr-c.c (avr_cpu_cpp_builtins): New built-in define > > __AVR_SFR_OFFSET__. > > * config/avr/avr-protos.h (out_movqi_r_mr, out_movqi_mr_r): Remove. > > (out_movhi_r_mr, out_movhi_mr_r): Remove. > > (out_movsi_r_mr, out_movsi_mr_r): Remove. > > * config/avr/avr.md (*cbi, *sbi): Use %i instead of %m-0x20. > > (*insv.io, *insv.not.io): Ditto. > > * config/avr/avr.c (out_movsi_r_mr, out_movsi_mr_r): Make static. > > (print_operand): Implement "%i" to print address as I/O address. > > (output_movqi): Clean up call of out_movqi_mr_r. > > (output_movhi): Clean up call of out_movhi_mr_r. > > (avr_file_start): Use avr_current_arch->sfr_offset instead of > > magic -0x20. Use TMP_REGNO, ZERO_REGNO instead of 0, 1. > > (avr_out_sbxx_branch): Use %i instead of %m-0x20. > > (out_movqi_r_mr, out_movqi_mr_r): Ditto. And make static. > > (out_movhi_r_mr, out_movhi_mr_r): Ditto. And use avr_asm_len. > > (out_shift_with_cnt): Clean up code: Use avr_asm_len. > > (output_movsisf): Use output_reload_insisf for all CONSTANT_P sources. > > (avr_out_movpsi): USE avr_out_reload_inpsi for all CONSTANT_P sources. > > Clean up call of avr_out_store_psi. > > (output_reload_in_const): Don't cut symbols longer than 2 bytes. > > (output_reload_insisf): Filter CONST_INT_P or CONST_DOUBLE_P to > > try if setting pre-cleared register is advantageous. > > (avr_out_plus_1): Use gen_int_mode instead of GEN_INT. > > This adds %i support for CONST_INT. > > It is needed because some insns don't use memory_operand but > mem:QI (io_address_operand) > > %i(mem) just forwards to %i(const_int) > > Ok? > > Johann > > * config/avr/avr.c (print_operand): Support code = 'i' for CONST_INT. > Ok. Denis.
Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 181717) +++ config/avr/avr.md (working copy) @@ -28,8 +28,8 @@ ;; j Branch condition. ;; k Reverse branch condition. ;;..m..Constant Direct Data memory address. -;; i Print the SFR address quivalent of a CONST_INT RAM address. -;; The resulting addres is suitable to be used in IN/OUT. +;; i Print the SFR address quivalent of a CONST_INT or a CONST_INT +;; RAM address. The resulting addres is suitable to be used in IN/OUT. ;; o Displacement for (mem (plus (reg) (const_int))) operands. ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z) ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30) Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 181717) +++ config/avr/avr.c (working copy) @@ -1822,9 +1822,32 @@ print_operand (FILE *file, rtx x, int co else fprintf (file, reg_names[true_regnum (x) + abcd]); } - else if (GET_CODE (x) == CONST_INT) - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd); - else if (GET_CODE (x) == MEM) + else if (CONST_INT_P (x)) + { + HOST_WIDE_INT ival = INTVAL (x); + + if ('i' != code) + fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd); + else if (low_io_address_operand (x, VOIDmode) + || high_io_address_operand (x, VOIDmode)) + { + switch (ival) + { + case RAMPZ_ADDR: fprintf (file, "__RAMPZ__"); break; + case SREG_ADDR: fprintf (file, "__SREG__"); break; + case SP_ADDR: fprintf (file, "__SP_L__"); break; + case SP_ADDR+1: fprintf (file, "__SP_H__"); break; + + default: + fprintf (file, HOST_WIDE_INT_PRINT_HEX, + ival - avr_current_arch->sfr_offset); + break; + } + } + else + fatal_insn ("bad address, not an I/O address:", x); + } + else if (MEM_P (x)) { rtx addr = XEXP (x, 0); @@ -1844,21 +1867,7 @@ print_operand (FILE *file, rtx x, int co } else if (code == 'i') { - if (!io_address_operand (addr, GET_MODE (x))) - fatal_insn ("bad address, not an I/O address:", addr); - - switch (INTVAL (addr)) - { - case RAMPZ_ADDR: fprintf (file, "__RAMPZ__"); break; - case SREG_ADDR: fprintf (file, "__SREG__"); break; - case SP_ADDR: fprintf (file, "__SP_L__"); break; - case SP_ADDR+1: fprintf (file, "__SP_H__"); break; - - default: - fprintf (file, HOST_WIDE_INT_PRINT_HEX, - UINTVAL (addr) - avr_current_arch->sfr_offset); - break; - } + print_operand (file, addr, 'i'); } else if (code == 'o') { @@ -1889,6 +1898,10 @@ print_operand (FILE *file, rtx x, int co else print_operand_address (file, addr); } + else if (code == 'i') + { + fatal_insn ("bad address, not an I/O address:", x); + } else if (code == 'x') { /* Constant progmem address - like used in jmp or call */