diff mbox

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

Message ID 4ECF7DC0.9080101@gjlay.de
State New
Headers show

Commit Message

Georg-Johann Lay Nov. 25, 2011, 11:36 a.m. UTC
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.

Comments

Denis Chertykov Nov. 25, 2011, 1:11 p.m. UTC | #1
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.
diff mbox

Patch

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 */