begnuas: simplify, add be_gas_emit_string()
authorMatthias Braun <matze@braunis.de>
Thu, 15 Nov 2012 09:28:04 +0000 (10:28 +0100)
committerMatthias Braun <matze@braunis.de>
Thu, 15 Nov 2012 09:32:29 +0000 (10:32 +0100)
simplify it by always using .asciz instead of sometimes .string/.ascii.
All new gcc/binutils understand .asciz.

ir/be/begnuas.c
ir/be/begnuas.h

index 46e1600..2ffa499 100644 (file)
@@ -755,38 +755,35 @@ static void emit_size_type(size_t size)
        }
 }
 
-static size_t emit_string_initializer(const ir_initializer_t *initializer)
+static void emit_string_char(int c)
 {
-       size_t i, len;
-
-       len = initializer->compound.n_initializers;
-       if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) {
-               be_emit_cstring("\t.ascii \"");
-       } else {
-               be_emit_cstring("\t.string \"");
-               len -= 1;
+       switch (c) {
+       case '"' : be_emit_cstring("\\\""); break;
+       case '\n': be_emit_cstring("\\n"); break;
+       case '\r': be_emit_cstring("\\r"); break;
+       case '\t': be_emit_cstring("\\t"); break;
+       case '\\': be_emit_cstring("\\\\"); break;
+       default  :
+               if (isprint(c))
+                       be_emit_char(c);
+               else
+                       be_emit_irprintf("\\%03o", c);
+               break;
        }
+}
 
-       for (i = 0; i < len; ++i) {
+static size_t emit_string_initializer(const ir_initializer_t *initializer)
+{
+       be_emit_cstring("\t.asciz \"");
+
+       size_t len = initializer->compound.n_initializers;
+       for (size_t i = 0; i < len-1; ++i) {
                const ir_initializer_t *sub_initializer
                        = get_initializer_compound_value(initializer, i);
 
                ir_tarval *tv = get_initializer_tarval(sub_initializer);
                int        c  = get_tarval_long(tv);
-
-               switch (c) {
-               case '"' : be_emit_cstring("\\\""); break;
-               case '\n': be_emit_cstring("\\n"); break;
-               case '\r': be_emit_cstring("\\r"); break;
-               case '\t': be_emit_cstring("\\t"); break;
-               case '\\': be_emit_cstring("\\\\"); break;
-               default  :
-                       if (isprint(c))
-                               be_emit_char(c);
-                       else
-                               be_emit_irprintf("\\%03o", c);
-                       break;
-               }
+               emit_string_char(c);
        }
        be_emit_cstring("\"\n");
        be_emit_write_line();
@@ -794,6 +791,16 @@ static size_t emit_string_initializer(const ir_initializer_t *initializer)
        return initializer->compound.n_initializers;
 }
 
+void be_gas_emit_cstring(const char *string)
+{
+       be_emit_cstring("\t.asciz \"");
+       for (const char *c = string; *c != '\0'; ++c) {
+               emit_string_char(*c);
+       }
+       be_emit_cstring("\"\n");
+       be_emit_write_line();
+}
+
 typedef enum normal_or_bitfield_kind {
        NORMAL = 0,
        TARVAL,
index 9f0bd08..8536679 100644 (file)
@@ -113,6 +113,11 @@ void be_gas_emit_block_name(const ir_node *block);
  */
 void be_gas_begin_block(const ir_node *block, bool needs_label);
 
+/**
+ * emit a string (takes care of escaping special chars)
+ */
+void be_gas_emit_cstring(const char *string);
+
 /**
  * Starts emitting a compilation unit. This emits:
  *  - global assembler snippets