From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jakub Jelinek To: binutils@sourceware.cygnus.com Cc: "David S. Miller" , Richard Henderson Subject: [PATCH] SPARC gas native wordsize insn support etc. Date: Thu, 01 Jul 1999 00:00:00 -0000 Message-id: <19990607192403.I949@mff.cuni.cz> X-SW-Source: 1999-q2/msg00157.html Hi! This patch adds support for native wordsize instructions which Solaris as supports, e.g. one can do: x: .nword 256 sethi %hi(x), %l3 ldn [%l3 + %lo(x)], %o1 slln %o1, 12, %o2 and e.g. slln will be alias either to sllx or sll depending on what arch size it was assembled with. I think it is pretty useful. Also, it makes more strict checking for the %lo()/%hi() family of as macros, so that gas no more accepts things like ld [%lobar + 295], %g1 (why I do this? I'd like to use ld [%lo(bar+26)+36+%g1], %g5 syntax for R_SPARC_OLO10 (26 would be normal addend and 36 secondary addend, OLO10 computes the value as (((symbol + addend) & 0x3ff) + secondary addend) & 0x1fff. For reference, Solaris exits with error if '(' does not follow after %lo & family, terminating ')' is missing or if one does some math on the %lo() value. And what current gas supports is really not intuitive: %lobar + 295 means 295 will be addend in %lo() and will be cropped to 10 bits). In fact, in the long term I think expr.c should be tought about possible port specific operators which tc-sparc.c could register with it, so that gas would e.g. support any kind of math if there is O_constant inside of %lo() etc.). 1999-06-07 Jakub Jelinek * gas/config/tc-sparc.c (md_begin): Handle native wordsize aliases (slln etc.). (s_ncons): New function. (native_op_table): New table. (sparc_ip): Be more strict on %hi() etc., prepare assembler for R_SPARC_OLO10 handling. * opcodes/sparc-opc.c: Add aliases Solaris as supports. --- ./gas/config/tc-sparc.c.jj Thu Apr 22 10:10:40 1999 +++ ./gas/config/tc-sparc.c Wed Jun 2 17:54:51 1999 @@ -115,6 +115,7 @@ static void s_reserve PARAMS ((int)); static void s_common PARAMS ((int)); static void s_empty PARAMS ((int)); static void s_uacons PARAMS ((int)); +static void s_ncons PARAMS ((int)); const pseudo_typeS md_pseudo_table[] = { @@ -123,6 +124,7 @@ const pseudo_typeS md_pseudo_table[] = {"empty", s_empty, 0}, {"global", s_globl, 0}, {"half", cons, 2}, + {"nword", s_ncons, 0}, {"optim", s_ignore, 0}, {"proc", s_proc, 0}, {"reserve", s_reserve, 0}, @@ -184,6 +186,7 @@ struct sparc_it unsigned long opcode; struct nlist *nlistp; expressionS exp; + expressionS exp2; int pcrel; bfd_reloc_code_real_type reloc; }; @@ -613,6 +626,27 @@ md_show_usage (stream) #endif } +/* native operand size opcode translation */ +struct + { + char *name; + char *name32; + char *name64; + } native_op_table[] = +{ + {"ldn", "ld", "ldx"}, + {"ldna", "lda", "ldxa"}, + {"stn", "st", "stx"}, + {"stna", "sta", "stxa"}, + {"slln", "sll", "sllx"}, + {"srln", "srl", "srlx"}, + {"sran", "sra", "srax"}, + {"casn", "cas", "casx"}, + {"casna", "casa", "casxa"}, + {"clrn", "clr", "clrx"}, + {NULL, NULL, NULL}, +}; + /* sparc64 priviledged registers */ struct priv_reg_entry @@ -711,6 +745,30 @@ md_begin () && !strcmp (sparc_opcodes[i].name, name)); } + for (i = 0; native_op_table[i].name; i++) + { + const struct sparc_opcode *insn; + char *name = sparc_arch_size == 32 ? native_op_table[i].name32 : + native_op_table[i].name64; + insn = (struct sparc_opcode *)hash_find (op_hash, name); + if (insn == NULL) + { + fprintf (stderr, _("internal error: can't find opcode `%s' for `%s'\n"), + name, native_op_table[i].name); + lose = 1; + } + else + { + retval = hash_insert (op_hash, native_op_table[i].name, (PTR) insn); + if (retval != NULL) + { + fprintf (stderr, _("internal error: can't hash `%s': %s\n"), + sparc_opcodes[i].name, retval); + lose = 1; + } + } + } + if (lose) as_fatal (_("Broken assembler. No assembly attempted.")); @@ -1885,89 +1947,221 @@ sparc_ip (str, pinsn) if (*s == ' ') s++; - /* Check for %hi, etc. */ - if (*s == '%') - { - static struct ops { - /* The name as it appears in assembler. */ - char *name; - /* strlen (name), precomputed for speed */ - int len; - /* The reloc this pseudo-op translates to. */ - int reloc; - /* Non-zero if for v9 only. */ - int v9_p; - /* Non-zero if can be used in pc-relative contexts. */ - int pcrel_p;/*FIXME:wip*/ - } ops[] = { - /* hix/lox must appear before hi/lo so %hix won't be - mistaken for %hi. */ - { "hix", 3, BFD_RELOC_SPARC_HIX22, 1, 0 }, - { "lox", 3, BFD_RELOC_SPARC_LOX10, 1, 0 }, - { "hi", 2, BFD_RELOC_HI22, 0, 1 }, - { "lo", 2, BFD_RELOC_LO10, 0, 1 }, - { "hh", 2, BFD_RELOC_SPARC_HH22, 1, 1 }, - { "hm", 2, BFD_RELOC_SPARC_HM10, 1, 1 }, - { "lm", 2, BFD_RELOC_SPARC_LM22, 1, 1 }, - { "h44", 3, BFD_RELOC_SPARC_H44, 1, 0 }, - { "m44", 3, BFD_RELOC_SPARC_M44, 1, 0 }, - { "l44", 3, BFD_RELOC_SPARC_L44, 1, 0 }, - { "uhi", 3, BFD_RELOC_SPARC_HH22, 1, 0 }, - { "ulo", 3, BFD_RELOC_SPARC_HM10, 1, 0 }, - { NULL } - }; - struct ops *o; + { + char *s1; + char *op_arg = NULL; + expressionS op_exp; + bfd_reloc_code_real_type old_reloc = the_insn.reloc; - for (o = ops; o->name; o++) - if (strncmp (s + 1, o->name, o->len) == 0) + /* Check for %hi, etc. */ + if (*s == '%') + { + static struct ops { + /* The name as it appears in assembler. */ + char *name; + /* strlen (name), precomputed for speed */ + int len; + /* The reloc this pseudo-op translates to. */ + int reloc; + /* Non-zero if for v9 only. */ + int v9_p; + /* Non-zero if can be used in pc-relative contexts. */ + int pcrel_p;/*FIXME:wip*/ + } ops[] = { + /* hix/lox must appear before hi/lo so %hix won't be + mistaken for %hi. */ + { "hix", 3, BFD_RELOC_SPARC_HIX22, 1, 0 }, + { "lox", 3, BFD_RELOC_SPARC_LOX10, 1, 0 }, + { "hi", 2, BFD_RELOC_HI22, 0, 1 }, + { "lo", 2, BFD_RELOC_LO10, 0, 1 }, + { "hh", 2, BFD_RELOC_SPARC_HH22, 1, 1 }, + { "hm", 2, BFD_RELOC_SPARC_HM10, 1, 1 }, + { "lm", 2, BFD_RELOC_SPARC_LM22, 1, 1 }, + { "h44", 3, BFD_RELOC_SPARC_H44, 1, 0 }, + { "m44", 3, BFD_RELOC_SPARC_M44, 1, 0 }, + { "l44", 3, BFD_RELOC_SPARC_L44, 1, 0 }, + { "uhi", 3, BFD_RELOC_SPARC_HH22, 1, 0 }, + { "ulo", 3, BFD_RELOC_SPARC_HM10, 1, 0 }, + { NULL } + }; + struct ops *o; + + for (o = ops; o->name; o++) + if (strncmp (s + 1, o->name, o->len) == 0) + break; + if (o->name == NULL) break; - if (o->name == NULL) - break; + + if (s[o->len + 1] != '(') + { + as_bad (_("Illegal operands: %%%s requires arguments in ()"), o->name); + return; + } - the_insn.reloc = o->reloc; - s += o->len + 1; - v9_arg_p = o->v9_p; - } + op_arg = o->name; + the_insn.reloc = o->reloc; + s += o->len + 2; + v9_arg_p = o->v9_p; + } + + /* Note that if the get_expression() fails, we will still + have created U entries in the symbol table for the + 'symbols' in the input string. Try not to create U + symbols for registers, etc. */ - /* Note that if the get_expression() fails, we will still - have created U entries in the symbol table for the - 'symbols' in the input string. Try not to create U - symbols for registers, etc. */ - { /* This stuff checks to see if the expression ends in +%reg. If it does, it removes the register from the expression, and re-sets 's' to point to the right place. */ - char *s1; + if (op_arg) + { + int npar = 0; + + for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) + if (*s1 == '(') + npar++; + else if (*s1 == ')') + { + if (!npar) + break; + npar--; + } + + if (*s1 != ')') + { + as_bad (_("Illegal operands: %%%s requires arguments in ()"), op_arg); + return; + } + + *s1 = '\0'; + (void) get_expression (s); + *s1 = ')'; + s = s1 + 1; + if (*s == ',' || *s == ']' || !*s) + continue; + if (*s != '+' && *s != '-') + { + as_bad (_("Illegal operands: Can't do arithmetics other than + and - involving %%%s()"), op_arg); + return; + } + *s1 = '0'; + s = s1; + op_exp = the_insn.exp; + memset (&the_insn.exp, 0, sizeof(the_insn.exp)); + } for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ; if (s1 != s && isdigit ((unsigned char) s1[-1])) { if (s1[-2] == '%' && s1[-3] == '+') + s1 -= 3; + else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+') + s1 -= 4; + else + s1 = NULL; + if (s1) { - s1 -= 3; *s1 = '\0'; (void) get_expression (s); *s1 = '+'; + if (op_arg) + *s = ')'; s = s1; - continue; } - else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+') + } + else + s1 = NULL; + + if (!s1) + { + (void) get_expression (s); + if (op_arg) + *s = ')'; + s = expr_end; + } + + if (op_arg) + { + the_insn.exp2 = the_insn.exp; + the_insn.exp = op_exp; + if (the_insn.exp2.X_op == O_absent) + the_insn.exp2.X_op = O_illegal; + else if (the_insn.exp.X_op == O_absent) { - s1 -= 4; - *s1 = '\0'; - (void) get_expression (s); - *s1 = '+'; - s = s1; - continue; + the_insn.exp = the_insn.exp2; + the_insn.exp2.X_op = O_illegal; + } + else if (the_insn.exp.X_op == O_constant) + { + valueT val = the_insn.exp.X_add_number; + switch (the_insn.reloc) + { + case BFD_RELOC_SPARC_HH22: + val = BSR (val, 32); + /* intentional fallthrough */ + + case BFD_RELOC_SPARC_LM22: + case BFD_RELOC_HI22: + val = (val >> 10) & 0x3fffff; + break; + + case BFD_RELOC_SPARC_HM10: + val = BSR (val, 32); + /* intentional fallthrough */ + + case BFD_RELOC_LO10: + val &= 0x3ff; + break; + + case BFD_RELOC_SPARC_H44: + val >>= 22; + val &= 0x3fffff; + break; + + case BFD_RELOC_SPARC_M44: + val >>= 12; + val &= 0x3ff; + break; + + case BFD_RELOC_SPARC_L44: + val &= 0xfff; + break; + + case BFD_RELOC_SPARC_HIX22: + val = ~ val; + val = (val >> 10) & 0x3fffff; + break; + + case BFD_RELOC_SPARC_LOX10: + val = (val & 0x3ff) | 0x1c00; + break; + } + the_insn.exp = the_insn.exp2; + the_insn.exp.X_add_number += val; + the_insn.exp2.X_op = O_illegal; + the_insn.reloc = old_reloc; + } + else if (the_insn.exp2.X_op != O_constant) + { + as_bad (_("Illegal operands: Can't add non-constant expression to %%%s()"), op_arg); + return; + } + else + { + if (1 || old_reloc != BFD_RELOC_SPARC13 + || the_insn.reloc != BFD_RELOC_LO10 + || sparc_arch_size != 64 + || sparc_pic_code) + { + as_bad (_("Illegal operands: Can't do arithmetics involving %%%s() of a relocatable symbol"), op_arg); + return; + } + the_insn.reloc = BFD_RELOC_SPARC_OLO10; } } } - (void) get_expression (s); - s = expr_end; - /* Check for constants that don't require emitting a reloc. */ if (the_insn.exp.X_op == O_constant && the_insn.exp.X_add_symbol == 0 @@ -3392,6 +3601,17 @@ s_uacons (bytes) /* Tell sparc_cons_align not to align this value. */ sparc_no_align_cons = 1; cons (bytes); +} + +/* This handles the native word allocation pseudo-op .nword. + For sparc_arch_size 32 it is equivalent to .word, for + sparc_arch_size 64 it is equivalent to .xword. */ + +static void +s_ncons (bytes) + int bytes; +{ + cons (sparc_arch_size == 32 ? 4 : 8); } /* If the --enforce-aligned-data option is used, we require .word, --- ./opcodes/sparc-opc.c.jj Thu Apr 22 10:13:34 1999 +++ ./opcodes/sparc-opc.c Tue May 25 17:19:05 1999 @@ -1,5 +1,5 @@ /* Table of opcodes for the sparc. - Copyright (C) 1989, 91, 92, 93, 94, 95, 96, 97, 1998 + Copyright (C) 1989, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of the BFD library. @@ -378,7 +390,7 @@ const struct sparc_opcode sparc_opcodes[ { "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|RS1_G0, "[i]o,d", F_ALIAS, v9 }, { "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|SIMM13(~0), "[1]o,d", F_ALIAS, v9 }, /* ld [rs1+0],d */ -{ "ldxa", F3(3, 0x1b, 0), F3(~3, ~0x1b, ~0), "[1+2]A,d", 0, v9 }, /* lduwa === lda */ +{ "ldxa", F3(3, 0x1b, 0), F3(~3, ~0x1b, ~0), "[1+2]A,d", 0, v9 }, { "ldxa", F3(3, 0x1b, 0), F3(~3, ~0x1b, ~0)|RS2_G0, "[1]A,d", 0, v9 }, /* lda [rs1+%g0],d */ { "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1), "[1+i]o,d", 0, v9 }, { "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1), "[i+1]o,d", 0, v9 }, @@ -424,6 +436,25 @@ const struct sparc_opcode sparc_opcodes[ { "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", F_ALIAS, v9 }, { "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", F_ALIAS, v9 }, { "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+0] */ +{ "stsw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v9 }, +{ "stsw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+%g0] */ +{ "stsw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]", F_ALIAS, v9 }, +{ "stsw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", F_ALIAS, v9 }, +{ "stsw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", F_ALIAS, v9 }, +{ "stsw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+0] */ +{ "stuw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v9 }, +{ "stuw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+%g0] */ +{ "stuw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]", F_ALIAS, v9 }, +{ "stuw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", F_ALIAS, v9 }, +{ "stuw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", F_ALIAS, v9 }, +{ "stuw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+0] */ + +{ "spill", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, +{ "spill", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* st d,[rs1+%g0] */ +{ "spill", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]", F_ALIAS, v6 }, +{ "spill", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", F_ALIAS, v6 }, +{ "spill", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, +{ "spill", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* st d,[rs1+0] */ { "sta", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A", 0, v6 }, { "sta", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* sta d,[rs1+%g0] */ @@ -445,6 +476,18 @@ const struct sparc_opcode sparc_opcodes[ { "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o", F_ALIAS, v9 }, { "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, { "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* st d,[rs1+0] */ +{ "stswa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A", F_ALIAS, v9 }, +{ "stswa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v9 }, /* sta d,[rs1+%g0] */ +{ "stswa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[1+i]o", F_ALIAS, v9 }, +{ "stswa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o", F_ALIAS, v9 }, +{ "stswa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, +{ "stswa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* st d,[rs1+0] */ +{ "stuwa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A", F_ALIAS, v9 }, +{ "stuwa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v9 }, /* sta d,[rs1+%g0] */ +{ "stuwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[1+i]o", F_ALIAS, v9 }, +{ "stuwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o", F_ALIAS, v9 }, +{ "stuwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, +{ "stuwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* st d,[rs1+0] */ { "stb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI(~0), "d,[1+2]", 0, v6 }, { "stb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI_RS2(~0), "d,[1]", 0, v6 }, /* stb d,[rs1+%g0] */ @@ -453,6 +496,19 @@ const struct sparc_opcode sparc_opcodes[ { "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RS1_G0, "d,[i]", 0, v6 }, { "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* stb d,[rs1+0] */ +{ "stsb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, +{ "stsb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* stb d,[rs1+%g0] */ +{ "stsb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[1+i]", F_ALIAS, v6 }, +{ "stsb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[i+1]", F_ALIAS, v6 }, +{ "stsb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, +{ "stsb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* stb d,[rs1+0] */ +{ "stub", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, +{ "stub", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* stb d,[rs1+%g0] */ +{ "stub", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[1+i]", F_ALIAS, v6 }, +{ "stub", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[i+1]", F_ALIAS, v6 }, +{ "stub", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, +{ "stub", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* stb d,[rs1+0] */ + { "stba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0), "d,[1+2]A", 0, v6 }, { "stba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* stba d,[rs1+%g0] */ { "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[1+i]o", 0, v9 }, @@ -460,6 +516,19 @@ const struct sparc_opcode sparc_opcodes[ { "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|RS1_G0, "d,[i]o", 0, v9 }, { "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* stb d,[rs1+0] */ +{ "stsba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0), "d,[1+2]A", F_ALIAS, v6 }, +{ "stsba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v6 }, /* stba d,[rs1+%g0] */ +{ "stsba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[1+i]o", F_ALIAS, v9 }, +{ "stsba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[i+1]o", F_ALIAS, v9 }, +{ "stsba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, +{ "stsba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* stb d,[rs1+0] */ +{ "stuba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0), "d,[1+2]A", F_ALIAS, v6 }, +{ "stuba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v6 }, /* stba d,[rs1+%g0] */ +{ "stuba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[1+i]o", F_ALIAS, v9 }, +{ "stuba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[i+1]o", F_ALIAS, v9 }, +{ "stuba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, +{ "stuba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* stb d,[rs1+0] */ + { "std", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI(~0), "d,[1+2]", 0, v6 }, { "std", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI_RS2(~0), "d,[1]", 0, v6 }, /* std d,[rs1+%g0] */ { "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[1+i]", 0, v6 }, @@ -493,6 +562,13 @@ const struct sparc_opcode sparc_opcodes[ { "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0, "D,[i]", 0, v6notv9 }, { "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0), "D,[1]", 0, v6notv9 }, /* std d,[rs1+0] */ +{ "spilld", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, +{ "spilld", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* std d,[rs1+%g0] */ +{ "spilld", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[1+i]", F_ALIAS, v6 }, +{ "spilld", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[i+1]", F_ALIAS, v6 }, +{ "spilld", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, +{ "spilld", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* std d,[rs1+0] */ + { "stda", F3(3, 0x17, 0), F3(~3, ~0x17, ~0), "d,[1+2]A", 0, v6 }, { "stda", F3(3, 0x17, 0), F3(~3, ~0x17, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* stda d,[rs1+%g0] */ { "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1), "d,[1+i]o", 0, v9 }, @@ -513,6 +589,19 @@ const struct sparc_opcode sparc_opcodes[ { "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RS1_G0, "d,[i]", 0, v6 }, { "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* sth d,[rs1+0] */ +{ "stsh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, +{ "stsh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* sth d,[rs1+%g0] */ +{ "stsh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[1+i]", F_ALIAS, v6 }, +{ "stsh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[i+1]", F_ALIAS, v6 }, +{ "stsh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, +{ "stsh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* sth d,[rs1+0] */ +{ "stuh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, +{ "stuh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* sth d,[rs1+%g0] */ +{ "stuh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[1+i]", F_ALIAS, v6 }, +{ "stuh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[i+1]", F_ALIAS, v6 }, +{ "stuh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, +{ "stuh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* sth d,[rs1+0] */ + { "stha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0), "d,[1+2]A", 0, v6 }, { "stha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* stha ,[rs1+%g0] */ { "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[1+i]o", 0, v9 }, @@ -520,6 +609,19 @@ const struct sparc_opcode sparc_opcodes[ { "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|RS1_G0, "d,[i]o", 0, v9 }, { "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* sth d,[rs1+0] */ +{ "stsha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0), "d,[1+2]A", F_ALIAS, v6 }, +{ "stsha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v6 }, /* stha ,[rs1+%g0] */ +{ "stsha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[1+i]o", F_ALIAS, v9 }, +{ "stsha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[i+1]o", F_ALIAS, v9 }, +{ "stsha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, +{ "stsha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* sth d,[rs1+0] */ +{ "stuha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0), "d,[1+2]A", F_ALIAS, v6 }, +{ "stuha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v6 }, /* stha ,[rs1+%g0] */ +{ "stuha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[1+i]o", F_ALIAS, v9 }, +{ "stuha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[i+1]o", F_ALIAS, v9 }, +{ "stuha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, +{ "stuha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* sth d,[rs1+0] */ + { "stx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|ASI(~0), "d,[1+2]", 0, v9 }, { "stx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|ASI_RS2(~0), "d,[1]", 0, v9 }, /* stx d,[rs1+%g0] */ { "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1), "d,[1+i]", 0, v9 }, @@ -1444,33 +1546,42 @@ CONDFC ("fbule", "cb013", 0xe, 0), { "fdivd", F3F(2, 0x34, 0x04e), F3F(~2, ~0x34, ~0x04e), "v,B,H", F_FLOAT, v6 }, { "fdivq", F3F(2, 0x34, 0x04f), F3F(~2, ~0x34, ~0x04f), "V,R,J", F_FLOAT, v8 }, +{ "fdivx", F3F(2, 0x34, 0x04f), F3F(~2, ~0x34, ~0x04f), "V,R,J", F_FLOAT|F_ALIAS, v8 }, { "fdivs", F3F(2, 0x34, 0x04d), F3F(~2, ~0x34, ~0x04d), "e,f,g", F_FLOAT, v6 }, { "fmuld", F3F(2, 0x34, 0x04a), F3F(~2, ~0x34, ~0x04a), "v,B,H", F_FLOAT, v6 }, { "fmulq", F3F(2, 0x34, 0x04b), F3F(~2, ~0x34, ~0x04b), "V,R,J", F_FLOAT, v8 }, +{ "fmulx", F3F(2, 0x34, 0x04b), F3F(~2, ~0x34, ~0x04b), "V,R,J", F_FLOAT|F_ALIAS, v8 }, { "fmuls", F3F(2, 0x34, 0x049), F3F(~2, ~0x34, ~0x049), "e,f,g", F_FLOAT, v6 }, { "fdmulq", F3F(2, 0x34, 0x06e), F3F(~2, ~0x34, ~0x06e), "v,B,J", F_FLOAT, v8 }, +{ "fdmulx", F3F(2, 0x34, 0x06e), F3F(~2, ~0x34, ~0x06e), "v,B,J", F_FLOAT|F_ALIAS, v8 }, { "fsmuld", F3F(2, 0x34, 0x069), F3F(~2, ~0x34, ~0x069), "e,f,H", F_FLOAT, v8 }, { "fsqrtd", F3F(2, 0x34, 0x02a), F3F(~2, ~0x34, ~0x02a)|RS1_G0, "B,H", F_FLOAT, v7 }, { "fsqrtq", F3F(2, 0x34, 0x02b), F3F(~2, ~0x34, ~0x02b)|RS1_G0, "R,J", F_FLOAT, v8 }, +{ "fsqrtx", F3F(2, 0x34, 0x02b), F3F(~2, ~0x34, ~0x02b)|RS1_G0, "R,J", F_FLOAT|F_ALIAS, v8 }, { "fsqrts", F3F(2, 0x34, 0x029), F3F(~2, ~0x34, ~0x029)|RS1_G0, "f,g", F_FLOAT, v7 }, { "fabsd", F3F(2, 0x34, 0x00a), F3F(~2, ~0x34, ~0x00a)|RS1_G0, "B,H", F_FLOAT, v9 }, { "fabsq", F3F(2, 0x34, 0x00b), F3F(~2, ~0x34, ~0x00b)|RS1_G0, "R,J", F_FLOAT, v9 }, +{ "fabsx", F3F(2, 0x34, 0x00b), F3F(~2, ~0x34, ~0x00b)|RS1_G0, "R,J", F_FLOAT|F_ALIAS, v9 }, { "fabss", F3F(2, 0x34, 0x009), F3F(~2, ~0x34, ~0x009)|RS1_G0, "f,g", F_FLOAT, v6 }, { "fmovd", F3F(2, 0x34, 0x002), F3F(~2, ~0x34, ~0x002)|RS1_G0, "B,H", F_FLOAT, v9 }, { "fmovq", F3F(2, 0x34, 0x003), F3F(~2, ~0x34, ~0x003)|RS1_G0, "R,J", F_FLOAT, v9 }, +{ "fmovx", F3F(2, 0x34, 0x003), F3F(~2, ~0x34, ~0x003)|RS1_G0, "R,J", F_FLOAT|F_ALIAS, v9 }, { "fmovs", F3F(2, 0x34, 0x001), F3F(~2, ~0x34, ~0x001)|RS1_G0, "f,g", F_FLOAT, v6 }, { "fnegd", F3F(2, 0x34, 0x006), F3F(~2, ~0x34, ~0x006)|RS1_G0, "B,H", F_FLOAT, v9 }, { "fnegq", F3F(2, 0x34, 0x007), F3F(~2, ~0x34, ~0x007)|RS1_G0, "R,J", F_FLOAT, v9 }, +{ "fnegx", F3F(2, 0x34, 0x007), F3F(~2, ~0x34, ~0x007)|RS1_G0, "R,J", F_FLOAT|F_ALIAS, v9 }, { "fnegs", F3F(2, 0x34, 0x005), F3F(~2, ~0x34, ~0x005)|RS1_G0, "f,g", F_FLOAT, v6 }, { "faddd", F3F(2, 0x34, 0x042), F3F(~2, ~0x34, ~0x042), "v,B,H", F_FLOAT, v6 }, { "faddq", F3F(2, 0x34, 0x043), F3F(~2, ~0x34, ~0x043), "V,R,J", F_FLOAT, v8 }, +{ "faddx", F3F(2, 0x34, 0x043), F3F(~2, ~0x34, ~0x043), "V,R,J", F_FLOAT|F_ALIAS, v8 }, { "fadds", F3F(2, 0x34, 0x041), F3F(~2, ~0x34, ~0x041), "e,f,g", F_FLOAT, v6 }, { "fsubd", F3F(2, 0x34, 0x046), F3F(~2, ~0x34, ~0x046), "v,B,H", F_FLOAT, v6 }, { "fsubq", F3F(2, 0x34, 0x047), F3F(~2, ~0x34, ~0x047), "V,R,J", F_FLOAT, v8 }, +{ "fsubx", F3F(2, 0x34, 0x047), F3F(~2, ~0x34, ~0x047), "V,R,J", F_FLOAT|F_ALIAS, v8 }, { "fsubs", F3F(2, 0x34, 0x045), F3F(~2, ~0x34, ~0x045), "e,f,g", F_FLOAT, v6 }, #define CMPFCC(x) (((x)&0x3)<<25) @@ -1495,6 +1606,16 @@ CONDFC ("fbule", "cb013", 0xe, 0), { "fcmpeq", CMPFCC(1)|F3F(2, 0x35, 0x057), CMPFCC(~1)|F3F(~2, ~0x35, ~0x057), "7,V,R", F_FLOAT, v9 }, { "fcmpeq", CMPFCC(2)|F3F(2, 0x35, 0x057), CMPFCC(~2)|F3F(~2, ~0x35, ~0x057), "8,V,R", F_FLOAT, v9 }, { "fcmpeq", CMPFCC(3)|F3F(2, 0x35, 0x057), CMPFCC(~3)|F3F(~2, ~0x35, ~0x057), "9,V,R", F_FLOAT, v9 }, +{ "fcmpx", F3F(2, 0x35, 0x053), F3F(~2, ~0x35, ~0x053)|RD_G0, "V,R", F_FLOAT|F_ALIAS, v8 }, +{ "fcmpx", CMPFCC(0)|F3F(2, 0x35, 0x053), CMPFCC(~0)|F3F(~2, ~0x35, ~0x053), "6,V,R", F_FLOAT|F_ALIAS, v9 }, +{ "fcmpx", CMPFCC(1)|F3F(2, 0x35, 0x053), CMPFCC(~1)|F3F(~2, ~0x35, ~0x053), "7,V,R", F_FLOAT|F_ALIAS, v9 }, +{ "fcmpx", CMPFCC(2)|F3F(2, 0x35, 0x053), CMPFCC(~2)|F3F(~2, ~0x35, ~0x053), "8,V,R", F_FLOAT|F_ALIAS, v9 }, +{ "fcmpx", CMPFCC(3)|F3F(2, 0x35, 0x053), CMPFCC(~3)|F3F(~2, ~0x35, ~0x053), "9,V,R", F_FLOAT|F_ALIAS, v9 }, +{ "fcmpex", F3F(2, 0x35, 0x057), F3F(~2, ~0x35, ~0x057)|RD_G0, "V,R", F_FLOAT|F_ALIAS, v8 }, +{ "fcmpex", CMPFCC(0)|F3F(2, 0x35, 0x057), CMPFCC(~0)|F3F(~2, ~0x35, ~0x057), "6,V,R", F_FLOAT|F_ALIAS, v9 }, +{ "fcmpex", CMPFCC(1)|F3F(2, 0x35, 0x057), CMPFCC(~1)|F3F(~2, ~0x35, ~0x057), "7,V,R", F_FLOAT|F_ALIAS, v9 }, +{ "fcmpex", CMPFCC(2)|F3F(2, 0x35, 0x057), CMPFCC(~2)|F3F(~2, ~0x35, ~0x057), "8,V,R", F_FLOAT|F_ALIAS, v9 }, +{ "fcmpex", CMPFCC(3)|F3F(2, 0x35, 0x057), CMPFCC(~3)|F3F(~2, ~0x35, ~0x057), "9,V,R", F_FLOAT|F_ALIAS, v9 }, { "fcmps", F3F(2, 0x35, 0x051), F3F(~2, ~0x35, ~0x051)|RD_G0, "e,f", F_FLOAT, v6 }, { "fcmps", CMPFCC(0)|F3F(2, 0x35, 0x051), CMPFCC(~0)|F3F(~2, ~0x35, ~0x051), "6,e,f", F_FLOAT, v9 }, { "fcmps", CMPFCC(1)|F3F(2, 0x35, 0x051), CMPFCC(~1)|F3F(~2, ~0x35, ~0x051), "7,e,f", F_FLOAT, v9 }, Cheers, Jakub ___________________________________________________________________ Jakub Jelinek | jj@sunsite.mff.cuni.cz | http://sunsite.mff.cuni.cz Administrator of SunSITE Czech Republic, MFF, Charles University ___________________________________________________________________ UltraLinux | http://ultra.linux.cz/ | http://ultra.penguin.cz/ Linux version 2.3.4 on a sparc64 machine (1343.49 BogoMips) ___________________________________________________________________