public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH REWORKED] gas: all: new macro directives: ifbin, ifconst, ifdec, iffloat, ifhex, ifnumber, ifquoted
@ 2020-02-12  5:13 Dmitrij V
  2020-03-23 17:30 ` Nick Clifton
  0 siblings, 1 reply; 2+ messages in thread
From: Dmitrij V @ 2020-02-12  5:13 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 991 bytes --]

.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 call a function with arg 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

[-- Attachment #2: new-macro-directives.diff --]
[-- Type: text/plain, Size: 5510 bytes --]

diff --git a/gas/cond.c b/gas/cond.c
index 9753369e18..19a1ea08ac 100644
--- a/gas/cond.c
+++ b/gas/cond.c
@@ -580,3 +580,195 @@ 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 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);
+
+    switch (arg) {
+      case 0: { do_skip = !is_number(label); break; }
+      case 2: { do_skip = !is_bin(label); break; }
+      case 10: { do_skip = !is_dec(label); break; }
+      case 16: { do_skip = !is_hex(label); break; }
+      case 128: { do_skip = !is_float(label); break; }
+      default : { do_skip = 1; break; }
+    }
+
+    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 c;
+
+    do_skip = 1;
+
+    SKIP_WHITESPACE ();
+
+    c = get_symbol_name(&label);
+    // printf("label: %s; c: %c\n",(label),(c));
+
+    if (*label == '$')
+      ++label;
+
+    if (c == '"' && !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..7754290606 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_ifnumber, 2},
   {"ifc", s_ifc, 0},
+  {"ifconst", s_ifconst, 0},
   {"ifdef", s_ifdef, 0},
+  {"ifdec", s_ifnumber, 10},
   {"ifeq", s_if, (int) O_eq},
   {"ifeqs", s_ifeqs, 0},
+  {"iffloat", s_ifnumber, 128},
   {"ifge", s_if, (int) O_ge},
   {"ifgt", s_if, (int) O_gt},
+  {"ifhex", s_ifnumber, 16},
   {"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..e1b4e79bac 100644
--- a/gas/read.h
+++ b/gas/read.h
@@ -186,8 +186,11 @@ extern void s_globl (int arg);
 extern void s_if (int arg);
 extern void s_ifb (int arg);
 extern void s_ifc (int arg);
+extern void s_ifconst (int);
 extern void s_ifdef (int arg);
 extern void s_ifeqs (int arg);
+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);

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH REWORKED] gas: all: new macro directives: ifbin, ifconst,  ifdec, iffloat, ifhex, ifnumber, ifquoted
  2020-02-12  5:13 [PATCH REWORKED] gas: all: new macro directives: ifbin, ifconst, ifdec, iffloat, ifhex, ifnumber, ifquoted Dmitrij V
@ 2020-03-23 17:30 ` Nick Clifton
  0 siblings, 0 replies; 2+ messages in thread
From: Nick Clifton @ 2020-03-23 17:30 UTC (permalink / raw)
  To: Dmitrij V, binutils

Hi Dmitrij,

  [Sorry for the long delay in replying to your email].

  Thanks for the patch.  It is looking good, but there are several
  things missing.  Speficially:

    * A ChangeLog entry to describe the patch.
    * An update to the gas/NEWS file mentioning the new directives.
    * A patch to gas/doc/as.texi describing the new directives.
    * A new test or two in the gas testsuite to check the behaviour of
      the new macros and to make sure that they continue to work in the
      future.
    * Formatting the code to follow the GNU Coding Standards
       https://www.gnu.org/prep/standards/

Cheers
  Nick

PS.  With regard to the GNU Coding Standards I am particularly
  thinking of the following:

    static int is_float(const char* str) {

  which should be:

    static int
    is_float (const char* str)
    {

  (Ie put the return type on a separate line, as well as the
  opening curly brace).

  Plus:

     switch (arg) {

  Which should be:
 
     switch (arg)
     {

  (Opening curly braces are almost always on a line on their own).

  Also - not really a coding standard thing, but helpful nonetheless:

    s_ifnumber (int arg)
    {
       (void)arg;

  Is better written as:

   s_ifnumber (int arg ATTRIBUTE_UNUSED)
   {

  I hope that this helps.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-03-23 17:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-12  5:13 [PATCH REWORKED] gas: all: new macro directives: ifbin, ifconst, ifdec, iffloat, ifhex, ifnumber, ifquoted Dmitrij V
2020-03-23 17:30 ` Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).