diff mbox

[AVR] : Add built-in to get flash segment

Message ID 4F4F7F37.1060708@gjlay.de
State New
Headers show

Commit Message

Georg-Johann Lay March 1, 2012, 1:52 p.m. UTC
This built-in basically returns the high byte of a 24-bit address.

It can be used to test at run time where a pointer points to (Flash or RAM).

Ok for trunk?

Johann

	* doc/extend.texi (AVR Built-in Functions): Document
	__builtin_avr_flash_segment.

	* config/avr/builtins.def (__builtin_avr_flash_segment): New entry.
	* config/avr/avr.md (flash_segment, flash_segment1): New expanders.
	(*split.flash_segment): New insn-and-split.
	* config/avr/avr.c (avr_init_builtins): Add local variables:
	const_memx_void_node, const_memx_ptr_type_node,
	char_ftype_const_memx_ptr.

Comments

Weddington, Eric March 1, 2012, 3:11 p.m. UTC | #1
> -----Original Message-----
> From: Georg-Johann Lay [mailto:avr@gjlay.de]
> Sent: Thursday, March 01, 2012 6:53 AM
> To: gcc-patches@gcc.gnu.org
> Cc: Denis Chertykov; Weddington, Eric
> Subject: [Patch,AVR]: Add built-in to get flash segment
> 
> This built-in basically returns the high byte of a 24-bit address.
> 
> It can be used to test at run time where a pointer points to (Flash or
RAM).
> 
> Ok for trunk?
> 

Please commit, thanks!

Eric
diff mbox

Patch

Index: doc/extend.texi
===================================================================
--- doc/extend.texi	(revision 184739)
+++ doc/extend.texi	(working copy)
@@ -8809,7 +8809,18 @@  might increase delay time. @code{ticks}
 integer constant; delays with a variable number of cycles are not supported.
 
 @smallexample
-     unsigned char __builtin_avr_insert_bits (unsigned long map, unsigned char bits, unsigned char val)
+char __builtin_avr_flash_segment (const __memx void*)
+@end smallexample
+
+@noindent
+This built-in takes a byte address to the 24-bit
+@ref{AVR Named Address Spaces,address space} @code{__memx} and returns
+the number of the flash segment (the 64 KiB chunk) where the address
+points to.  Counting starts at @code{0}.
+If the address does not point to flash memory, return @code{-1}.
+
+@smallexample
+unsigned char __builtin_avr_insert_bits (unsigned long map, unsigned char bits, unsigned char val)
 @end smallexample
 
 @noindent
Index: config/avr/builtins.def
===================================================================
--- config/avr/builtins.def	(revision 184659)
+++ config/avr/builtins.def	(working copy)
@@ -48,3 +48,4 @@  DEF_BUILTIN ("__builtin_avr_fmulsu", 2,
 /* More complex stuff that cannot be mapped 1:1 to an instruction.  */
 DEF_BUILTIN ("__builtin_avr_delay_cycles", -1, AVR_BUILTIN_DELAY_CYCLES, void_ftype_ulong, -1)
 DEF_BUILTIN ("__builtin_avr_insert_bits", 3, AVR_BUILTIN_INSERT_BITS, uchar_ftype_ulong_uchar_uchar, CODE_FOR_insert_bits)
+DEF_BUILTIN ("__builtin_avr_flash_segment", 1, AVR_BUILTIN_FLASH_SEGMENT, char_ftype_const_memx_ptr, CODE_FOR_flash_segment)
Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md	(revision 184659)
+++ config/avr/avr.md	(working copy)
@@ -5393,6 +5393,53 @@  (define_insn "insert_bits"
    (set_attr "cc" "clobber")])
 
 
+;; __builtin_avr_flash_segment
+
+;; Just a helper for the next "official" expander.
+
+(define_expand "flash_segment1"
+  [(set (match_operand:QI 0 "register_operand" "")
+        (subreg:QI (match_operand:PSI 1 "register_operand" "")
+                   2))
+   (set (cc0)
+        (compare (match_dup 0)
+                 (const_int 0)))
+   (set (pc)
+        (if_then_else (ge (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 2 "" ""))
+                      (pc)))
+   (set (match_dup 0)
+        (const_int -1))])
+
+(define_expand "flash_segment"
+  [(parallel [(match_operand:QI 0 "register_operand" "")
+              (match_operand:PSI 1 "register_operand" "")])]
+  ""
+  {
+    rtx label = gen_label_rtx ();
+    emit (gen_flash_segment1 (operands[0], operands[1], label));
+    emit_label (label);
+    DONE;
+  })
+
+;; Actually, it's too late now to work out address spaces known at compiletime.
+;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
+;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
+;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
+
+(define_insn_and_split "*split.flash_segment"
+  [(set (match_operand:QI 0 "register_operand"                        "=d")
+        (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
+                               (match_operand:HI 2 "register_operand"  "r"))
+                   2))]
+  ""
+  { gcc_unreachable(); }
+  ""
+  [(set (match_dup 0)
+        (match_dup 1))])
+
+
 ;; Parity
 
 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 184661)
+++ config/avr/avr.c	(working copy)
@@ -10432,6 +10432,19 @@  avr_init_builtins (void)
                                 unsigned_char_type_node,
                                 NULL_TREE);
 
+  tree const_memx_void_node
+      = build_qualified_type (void_type_node,
+                              TYPE_QUAL_CONST
+                              | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX));
+
+  tree const_memx_ptr_type_node
+      = build_pointer_type_for_mode (const_memx_void_node, PSImode, false);
+  
+  tree char_ftype_const_memx_ptr
+      = build_function_type_list (char_type_node,
+                                  const_memx_ptr_type_node,
+                                  NULL);
+
 #define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, CODE)                       \
   add_builtin_function (NAME, TYPE, ID, BUILT_IN_MD, NULL, NULL_TREE);
 #include "builtins.def"