Re: [Patch,AVR]: Clean up SFR offset usage: %i for CONST_INT

2011-11-25 Thread Georg-Johann Lay
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 

Re: [Patch,AVR]: Clean up SFR offset usage: %i for CONST_INT

2011-11-25 Thread Denis Chertykov
2011/11/25 Georg-Johann Lay a...@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.