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.
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