gas: all: new macro directives: ifbin, ifconst, ifdec, iffloat, ifhex, ifnumber, ifquoted

Message ID CAL4kvVv=hGN8kBfp9-T1r=c3Tb=AK6ZcJhvRwoaXWbm9DXHrhQ@mail.gmail.com
State New
Headers show
Series
  • gas: all: new macro directives: ifbin, ifconst, ifdec, iffloat, ifhex, ifnumber, ifquoted
Related show

Commit Message

Dmitrij V Jan. 21, 2020, noon
.ifbin - check for digit in binary format (base 2)
.ifconst - check for constant or abs value
.ifdec - check for digit (base 10)
.iffloat - check for floating digit
.ifhex - check for hex digit (base 16)
.ifnumber - check for digit in format: bin, dec, float, hex
.ifquoted - check for string quoted by \" (not digits!)

[USAGE]
.section .text

.macro INVOKE arg1
  .set myvar, 1
  .ifquoted "\arg1\()"
    .warning "arg1 is string: \"\arg1\()\""
    .section .rodata
    tmp_string\@: .string "\arg1\()"
    # here we need to recall invoke with new arg1 point to tmp_string\@
    .section .text
  .else
    .ifconst "\arg1\()"
      .warning "arg1 is const: \"\arg1\()\""
    .endif;
    .ifhex "\arg1\()"
      .warning "arg1 is hex: \"\arg1\()\""
    .endif;
    .iffloat "\arg1\()"
      .warning "arg1 is float: \"\arg1\()\""
    .endif;
  .endif;
.endm;

INVOKE "hello world !" # quoted string

INVOKE 45646h # const, hex

INVOKE $321.999 # not const, float
[/USAGE]

--
the best regards

Patch

diff --git a/gas/cond.c b/gas/cond.c
index 9753369e18..5501c53395 100644
--- a/gas/cond.c
+++ b/gas/cond.c
@@ -580,3 +580,331 @@  cond_exit_macro (int nest)
       obstack_free (&cond_obstack, hold);
     }
 }
+
+static int is_float(const char* str) {
+  if (!str || !*str || !strchr(str, '.'))
+    return 0;
+  if (*str == '$')
+    ++str;
+  if (*str == '-')
+    ++str;
+  if (!*str || !(*str >= '0' || *str <= '9'))
+    return 0;
+  char* p;
+  strtold(str, &p);
+  return !*p;
+}
+
+static int is_dec(const char* str) {
+  if (!str || !*str)
+    return 0;
+  if (*str == '$')
+    ++str;
+  if (*str == '-')
+    ++str;
+  if (!*str || !(*str >= '0' || *str <= '9'))
+    return 0;
+  char* p;
+  strtoll(str, &p, 10);
+  return !*p;
+}
+
+static int is_bin(const char* str) {
+  if (!str || !*str)
+    return 0;
+  if (*str == '$')
+    ++str;
+  if (*str == '-')
+    ++str;
+  if (!*str || !(*str == '0' || *str == '1'))
+    return 0;
+  char* p;
+  strtoll(str, &p, 2);
+  return (!*p || *p == 'b' || *p == 'B');
+}
+
+static int is_hex(const char* str) {
+  if (!str || !*str)
+    return 0;
+  if (*str == '$')
+    ++str;
+  if (*str == '-')
+    ++str;
+  if (*str == '0')
+    ++str;
+  if (*str == 'x' || *str == 'X')
+    ++str;
+  if (!*str || !((*str >= '0' && *str <= '9')
+  || (*str >= 'A' && *str <= 'F')
+  || (*str >= 'a' && *str <= 'f')))
+    return 0;
+  char* p;
+  strtoll(str, &p, 16);
+  return (!*p || *p == 'h' || *p == 'H');
+}
+
+static int is_number(const char* str) {
+  return (is_dec(str) || is_hex(str) || is_bin(str) || is_float(str));
+}
+
+
+/* Checks for digit in binary format (base 2) */
+
+void
+s_ifbin (int arg)
+{
+  (void)arg;
+  struct conditional_frame cframe;
+
+  initialize_cframe (&cframe);
+
+  if (cframe.dead_tree)
+    cframe.ignoring = 1;
+  else
+  {
+    int do_skip;
+    char *label;
+
+    do_skip = 1;
+
+    SKIP_WHITESPACE ();
+
+    get_symbol_name(&label);
+
+    if (is_bin(label))
+      do_skip = 0;
+
+    cframe.ignoring = do_skip;
+  }
+
+  current_cframe =
+  (struct conditional_frame *) obstack_alloc (&cond_obstack, sizeof cframe);
+  memcpy (current_cframe, &cframe, sizeof cframe);
+
+  ignore_rest_of_line ();
+}
+
+/* Checks for digit (base 10) */
+
+void
+s_ifdec (int arg)
+{
+  (void)arg;
+  struct conditional_frame cframe;
+
+  initialize_cframe (&cframe);
+
+  if (cframe.dead_tree)
+    cframe.ignoring = 1;
+  else
+  {
+    int do_skip;
+    char *label;
+
+    do_skip = 1;
+
+    SKIP_WHITESPACE ();
+
+    get_symbol_name(&label);
+
+    if (is_dec(label))
+      do_skip = 0;
+
+    cframe.ignoring = do_skip;
+  }
+
+  current_cframe =
+  (struct conditional_frame *) obstack_alloc (&cond_obstack, sizeof cframe);
+  memcpy (current_cframe, &cframe, sizeof cframe);
+
+  ignore_rest_of_line ();
+}
+
+/* Checks for floating digit */
+
+void
+s_iffloat (int arg)
+{
+  (void)arg;
+  struct conditional_frame cframe;
+
+  initialize_cframe (&cframe);
+
+  if (cframe.dead_tree)
+    cframe.ignoring = 1;
+  else
+  {
+    int do_skip;
+    char *label;
+
+    do_skip = 1;
+
+    SKIP_WHITESPACE ();
+
+    get_symbol_name(&label);
+
+    if (is_float(label))
+      do_skip = 0;
+
+    cframe.ignoring = do_skip;
+  }
+
+  current_cframe =
+  (struct conditional_frame *) obstack_alloc (&cond_obstack, sizeof cframe);
+  memcpy (current_cframe, &cframe, sizeof cframe);
+
+  ignore_rest_of_line ();
+}
+
+/* Checks for digit in hex (base 16) */
+
+void
+s_ifhex (int arg)
+{
+  (void)arg;
+  struct conditional_frame cframe;
+
+  initialize_cframe (&cframe);
+
+  if (cframe.dead_tree)
+    cframe.ignoring = 1;
+  else
+  {
+    int do_skip;
+    char *label;
+
+    do_skip = 1;
+
+    SKIP_WHITESPACE ();
+
+    get_symbol_name(&label);
+
+    if (is_hex(label))
+      do_skip = 0;
+
+    cframe.ignoring = do_skip;
+  }
+
+  current_cframe =
+  (struct conditional_frame *) obstack_alloc (&cond_obstack, sizeof cframe);
+  memcpy (current_cframe, &cframe, sizeof cframe);
+
+  ignore_rest_of_line ();
+}
+
+/* Checks for digit in any format: float, hex, dec, bin */
+
+void
+s_ifnumber (int arg)
+{
+  (void)arg;
+  struct conditional_frame cframe;
+
+  initialize_cframe (&cframe);
+
+  if (cframe.dead_tree)
+    cframe.ignoring = 1;
+  else
+  {
+    int do_skip;
+    char *label;
+
+    do_skip = 1;
+
+    SKIP_WHITESPACE ();
+
+    get_symbol_name(&label);
+
+    if (is_number(label))
+      do_skip = 0;
+
+    cframe.ignoring = do_skip;
+  }
+
+  current_cframe =
+  (struct conditional_frame *) obstack_alloc (&cond_obstack, sizeof cframe);
+  memcpy (current_cframe, &cframe, sizeof cframe);
+
+  ignore_rest_of_line ();
+}
+
+/* Checks for string quoted by \". */
+
+void
+s_ifquoted (int arg)
+{
+  (void)arg;
+  struct conditional_frame cframe;
+
+  initialize_cframe (&cframe);
+
+  if (cframe.dead_tree)
+    cframe.ignoring = 1;
+  else
+  {
+    int do_skip;
+    char *label;
+    char delim;
+
+    do_skip = 1;
+
+    SKIP_WHITESPACE ();
+
+    delim = get_symbol_name(&label);
+    // printf("label: %s; delim: %c\n",(label),(delim));
+
+    if (delim == '"' && !symbol_find (label) && !is_number(label))
+      do_skip = 0;
+
+    cframe.ignoring = do_skip;
+  }
+
+  current_cframe =
+  (struct conditional_frame *) obstack_alloc (&cond_obstack, sizeof cframe);
+  memcpy (current_cframe, &cframe, sizeof cframe);
+
+  ignore_rest_of_line ();
+}
+
+/* Checks for constant (or abs value) */
+
+void
+s_ifconst (int arg)
+{
+  (void)arg;
+  struct conditional_frame cframe;
+
+  initialize_cframe (&cframe);
+
+  if (cframe.dead_tree)
+    cframe.ignoring = 1;
+  else
+  {
+    int do_skip;
+    char *label;
+
+    do_skip = 1;
+
+    SKIP_WHITESPACE ();
+
+    get_symbol_name(&label);
+
+    if (!symbol_find (label) && *label != '$' && is_number(label))
+      do_skip = 0;
+    else
+    {
+      expressionS operand;
+      expression_and_evaluate (&operand);
+      if (operand.X_op == O_constant)
+        do_skip = 0;
+    }
+
+    cframe.ignoring = do_skip;
+  }
+
+  current_cframe =
+  (struct conditional_frame *) obstack_alloc (&cond_obstack, sizeof cframe);
+  memcpy (current_cframe, &cframe, sizeof cframe);
+
+  ignore_rest_of_line ();
+}
diff --git a/gas/read.c b/gas/read.c
index bf594f12a2..194614fe8d 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -379,12 +379,17 @@  static const pseudo_typeS potable[] = {
   {"hword", cons, 2},
   {"if", s_if, (int) O_ne},
   {"ifb", s_ifb, 1},
+  {"ifbin", s_ifbin, 0},
   {"ifc", s_ifc, 0},
+  {"ifconst", s_ifconst, 0},
   {"ifdef", s_ifdef, 0},
+  {"ifdec", s_ifdec, 0},
   {"ifeq", s_if, (int) O_eq},
   {"ifeqs", s_ifeqs, 0},
+  {"iffloat", s_iffloat, 0},
   {"ifge", s_if, (int) O_ge},
   {"ifgt", s_if, (int) O_gt},
+  {"ifhex", s_ifhex, 0},
   {"ifle", s_if, (int) O_le},
   {"iflt", s_if, (int) O_lt},
   {"ifnb", s_ifb, 0},
@@ -393,6 +398,8 @@  static const pseudo_typeS potable[] = {
   {"ifne", s_if, (int) O_ne},
   {"ifnes", s_ifeqs, 1},
   {"ifnotdef", s_ifdef, 1},
+  {"ifnumber", s_ifnumber, 0},
+  {"ifquoted", s_ifquoted, 0},
   {"incbin", s_incbin, 0},
   {"include", s_include, 0},
   {"int", cons, 4},
diff --git a/gas/read.h b/gas/read.h
index 502f3b6f2d..b9d6f35995 100644
--- a/gas/read.h
+++ b/gas/read.h
@@ -185,9 +185,16 @@  extern void s_func (int);
 extern void s_globl (int arg);
 extern void s_if (int arg);
 extern void s_ifb (int arg);
+extern void s_ifbin (int);
 extern void s_ifc (int arg);
+extern void s_ifconst (int);
 extern void s_ifdef (int arg);
+extern void s_ifdec (int);
 extern void s_ifeqs (int arg);
+extern void s_iffloat (int);
+extern void s_ifhex (int);
+extern void s_ifnumber (int);
+extern void s_ifquoted (int);
 extern void s_ignore (int arg);
 extern void s_include (int arg);
 extern void s_irp (int arg);