X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=opcodes%2Fs390-mkopc.c;h=c593fb60792594ad71f479d5cbb2fb6ead1e1a67;hb=b3adc24a0713411ab38a21dc894dd40dbc5c8f4f;hp=24951db65d492151cfb01712582006b0f47e2239;hpb=5746fb46c853e631ce67f9969064721cca51f4c6;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c index 24951db65d..c593fb6079 100644 --- a/opcodes/s390-mkopc.c +++ b/opcodes/s390-mkopc.c @@ -1,5 +1,5 @@ /* s390-mkopc.c -- Generates opcode table out of s390-opc.txt - Copyright 2000, 2001, 2003, 2007 Free Software Foundation, Inc. + Copyright (C) 2000-2020 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU opcodes library. @@ -22,24 +22,7 @@ #include #include #include - -/* Taken from opcodes/s390.h */ -enum s390_opcode_mode_val - { - S390_OPCODE_ESA = 0, - S390_OPCODE_ZARCH - }; - -enum s390_opcode_cpu_val - { - S390_OPCODE_G5 = 0, - S390_OPCODE_G6, - S390_OPCODE_Z900, - S390_OPCODE_Z990, - S390_OPCODE_Z9_109, - S390_OPCODE_Z9_EC, - S390_OPCODE_Z10 - }; +#include "opcode/s390.h" struct op_struct { @@ -48,7 +31,8 @@ struct op_struct char format[16]; int mode_bits; int min_cpu; - + int flags; + unsigned long long sort_value; int no_nibbles; }; @@ -69,7 +53,7 @@ createTable (void) static void insertOpcode (char *opcode, char *mnemonic, char *format, - int min_cpu, int mode_bits) + int min_cpu, int mode_bits, int flags) { char *str; unsigned long long sort_value; @@ -113,6 +97,7 @@ insertOpcode (char *opcode, char *mnemonic, char *format, op_array[ix].no_nibbles = no_nibbles; op_array[ix].min_cpu = min_cpu; op_array[ix].mode_bits = mode_bits; + op_array[ix].flags = flags; no_ops++; } @@ -122,22 +107,48 @@ struct s390_cond_ext_format char extension[4]; }; -/* The mnemonic extensions for conditional branches used to replace +/* The mnemonic extensions for conditional jumps used to replace the '*' tag. */ -#define NUM_COND_EXTENSIONS 12 +#define NUM_COND_EXTENSIONS 20 const struct s390_cond_ext_format s390_cond_extensions[NUM_COND_EXTENSIONS] = -{ { '2', "h" }, /* jump on A high */ +{ { '1', "o" }, /* jump on overflow / if ones */ + { '2', "h" }, /* jump on A high */ + { '2', "p" }, /* jump on plus */ { '3', "nle" }, /* jump on not low or equal */ { '4', "l" }, /* jump on A low */ + { '4', "m" }, /* jump on minus / if mixed */ { '5', "nhe" }, /* jump on not high or equal */ { '6', "lh" }, /* jump on low or high */ { '7', "ne" }, /* jump on A not equal B */ + { '7', "nz" }, /* jump on not zero / if not zeros */ { '8', "e" }, /* jump on A equal B */ + { '8', "z" }, /* jump on zero / if zeros */ { '9', "nlh" }, /* jump on not low or high */ { 'a', "he" }, /* jump on high or equal */ { 'b', "nl" }, /* jump on A not low */ + { 'b', "nm" }, /* jump on not minus / if not mixed */ { 'c', "le" }, /* jump on low or equal */ { 'd', "nh" }, /* jump on A not high */ + { 'd', "np" }, /* jump on not plus */ + { 'e', "no" }, /* jump on not overflow / if not ones */ +}; + +/* The mnemonic extensions for conditional branches used to replace + the '$' tag. */ +#define NUM_CRB_EXTENSIONS 12 +const struct s390_cond_ext_format s390_crb_extensions[NUM_CRB_EXTENSIONS] = +{ { '2', "h" }, /* jump on A high */ + { '2', "nle" }, /* jump on not low or equal */ + { '4', "l" }, /* jump on A low */ + { '4', "nhe" }, /* jump on not high or equal */ + { '6', "ne" }, /* jump on A not equal B */ + { '6', "lh" }, /* jump on low or high */ + { '8', "e" }, /* jump on A equal B */ + { '8', "nlh" }, /* jump on not low or high */ + { 'a', "nl" }, /* jump on A not low */ + { 'a', "he" }, /* jump on high or equal */ + { 'c', "nh" }, /* jump on A not high */ + { 'c', "le" }, /* jump on low or equal */ }; /* As with insertOpcode instructions are added to the sorted opcode @@ -148,18 +159,20 @@ const struct s390_cond_ext_format s390_cond_extensions[NUM_COND_EXTENSIONS] = static void insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, - int min_cpu, int mode_bits) + int min_cpu, int mode_bits, int flags) { char *tag; - char prefix[5]; - char suffix[5]; - char number[5]; + char prefix[15]; + char suffix[15]; + char number[15]; int mask_start, i = 0, tag_found = 0, reading_number = 0; int number_p = 0, suffix_p = 0, prefix_p = 0; + const struct s390_cond_ext_format *ext_table; + int ext_table_length; - if (!(tag = strchr (mnemonic, '*'))) + if (!(tag = strpbrk (mnemonic, "*$"))) { - insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits); + insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits, flags); return; } @@ -217,15 +230,28 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, mask_start >>= 2; - for (i = 0; i < NUM_COND_EXTENSIONS; i++) + switch (*tag) + { + case '*': + ext_table = s390_cond_extensions; + ext_table_length = NUM_COND_EXTENSIONS; + break; + case '$': + ext_table = s390_crb_extensions; + ext_table_length = NUM_CRB_EXTENSIONS; + break; + default: fprintf (stderr, "Unknown tag char: %c\n", *tag); + } + + for (i = 0; i < ext_table_length; i++) { char new_mnemonic[15]; strcpy (new_mnemonic, prefix); - opcode[mask_start] = s390_cond_extensions[i].nibble; - strcat (new_mnemonic, s390_cond_extensions[i].extension); + opcode[mask_start] = ext_table[i].nibble; + strcat (new_mnemonic, ext_table[i].extension); strcat (new_mnemonic, suffix); - insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits); + insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits, flags); } return; @@ -233,7 +259,7 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, fprintf (stderr, "Malformed mnemonic: %s\n", mnemonic); } -static char file_header[] = +static const char file_header[] = "/* The opcode table. This file was generated by s390-mkopc.\n\n" " The format of the opcode table is:\n\n" " NAME OPCODE MASK OPERANDS\n\n" @@ -243,7 +269,10 @@ static char file_header[] = " which bits in the actual opcode must match OPCODE.\n" " OPERANDS is the list of operands.\n\n" " The disassembler reads the table in order and prints the first\n" - " instruction which matches. */\n\n" + " instruction which matches.\n" + " MODE_BITS - zarch or esa\n" + " MIN_CPU - number of the min cpu level required\n" + " FLAGS - instruction flags. */\n\n" "const struct s390_opcode s390_opcodes[] =\n {\n"; /* `dumpTable': write opcode table. */ @@ -255,7 +284,7 @@ dumpTable (void) int ix; /* Write hash table entries (slots). */ - printf (file_header); + printf ("%s", file_header); for (ix = 0; ix < no_ops; ix++) { @@ -263,12 +292,13 @@ dumpTable (void) for (str = op_array[ix].opcode; *str != 0; str++) if (*str == '?') *str = '0'; - printf ("OP%i(0x%sLL), ", + printf ("OP%i(0x%sLL), ", op_array[ix].no_nibbles*4, op_array[ix].opcode); printf ("MASK_%s, INSTR_%s, ", op_array[ix].format, op_array[ix].format); printf ("%i, ", op_array[ix].mode_bits); - printf ("%i}", op_array[ix].min_cpu); + printf ("%i, ", op_array[ix].min_cpu); + printf ("%i}", op_array[ix].flags); if (ix < no_ops-1) printf (",\n"); else @@ -283,7 +313,7 @@ int main (void) { char currentLine[256]; - + createTable (); /* Read opcode descriptions from `stdin'. For each mnemonic, @@ -293,63 +323,120 @@ main (void) char opcode[16]; char mnemonic[16]; char format[16]; - char description[64]; + char description[80]; char cpu_string[16]; char modes_string[16]; + char flags_string[80]; int min_cpu; int mode_bits; + int flag_bits; + int num_matched; char *str; - if (currentLine[0] == '#') - continue; + if (currentLine[0] == '#' || currentLine[0] == '\n') + continue; memset (opcode, 0, 8); - if (sscanf (currentLine, "%15s %15s %15s \"%[^\"]\" %15s %15s", - opcode, mnemonic, format, description, - cpu_string, modes_string) == 6) + num_matched = + sscanf (currentLine, "%15s %15s %15s \"%79[^\"]\" %15s %15s %79[^\n]", + opcode, mnemonic, format, description, + cpu_string, modes_string, flags_string); + if (num_matched != 6 && num_matched != 7) { - if (strcmp (cpu_string, "g5") == 0) - min_cpu = S390_OPCODE_G5; - else if (strcmp (cpu_string, "g6") == 0) - min_cpu = S390_OPCODE_G6; - else if (strcmp (cpu_string, "z900") == 0) - min_cpu = S390_OPCODE_Z900; - else if (strcmp (cpu_string, "z990") == 0) - min_cpu = S390_OPCODE_Z990; - else if (strcmp (cpu_string, "z9-109") == 0) - min_cpu = S390_OPCODE_Z9_109; - else if (strcmp (cpu_string, "z9-ec") == 0) - min_cpu = S390_OPCODE_Z9_EC; - else if (strcmp (cpu_string, "z10") == 0) - min_cpu = S390_OPCODE_Z10; - else { - fprintf (stderr, "Couldn't parse cpu string %s\n", cpu_string); - exit (1); - } + fprintf (stderr, "Couldn't scan line %s\n", currentLine); + exit (1); + } + + if (strcmp (cpu_string, "g5") == 0 + || strcmp (cpu_string, "arch3") == 0) + min_cpu = S390_OPCODE_G5; + else if (strcmp (cpu_string, "g6") == 0) + min_cpu = S390_OPCODE_G6; + else if (strcmp (cpu_string, "z900") == 0 + || strcmp (cpu_string, "arch5") == 0) + min_cpu = S390_OPCODE_Z900; + else if (strcmp (cpu_string, "z990") == 0 + || strcmp (cpu_string, "arch6") == 0) + min_cpu = S390_OPCODE_Z990; + else if (strcmp (cpu_string, "z9-109") == 0) + min_cpu = S390_OPCODE_Z9_109; + else if (strcmp (cpu_string, "z9-ec") == 0 + || strcmp (cpu_string, "arch7") == 0) + min_cpu = S390_OPCODE_Z9_EC; + else if (strcmp (cpu_string, "z10") == 0 + || strcmp (cpu_string, "arch8") == 0) + min_cpu = S390_OPCODE_Z10; + else if (strcmp (cpu_string, "z196") == 0 + || strcmp (cpu_string, "arch9") == 0) + min_cpu = S390_OPCODE_Z196; + else if (strcmp (cpu_string, "zEC12") == 0 + || strcmp (cpu_string, "arch10") == 0) + min_cpu = S390_OPCODE_ZEC12; + else if (strcmp (cpu_string, "z13") == 0 + || strcmp (cpu_string, "arch11") == 0) + min_cpu = S390_OPCODE_Z13; + else if (strcmp (cpu_string, "z14") == 0 + || strcmp (cpu_string, "arch12") == 0) + min_cpu = S390_OPCODE_ARCH12; + else if (strcmp (cpu_string, "z15") == 0 + || strcmp (cpu_string, "arch13") == 0) + min_cpu = S390_OPCODE_ARCH13; + else { + fprintf (stderr, "Couldn't parse cpu string %s\n", cpu_string); + exit (1); + } + + str = modes_string; + mode_bits = 0; + do { + if (strncmp (str, "esa", 3) == 0 + && (str[3] == 0 || str[3] == ',')) { + mode_bits |= 1 << S390_OPCODE_ESA; + str += 3; + } else if (strncmp (str, "zarch", 5) == 0 + && (str[5] == 0 || str[5] == ',')) { + mode_bits |= 1 << S390_OPCODE_ZARCH; + str += 5; + } else { + fprintf (stderr, "Couldn't parse modes string %s\n", + modes_string); + exit (1); + } + if (*str == ',') + str++; + } while (*str != 0); - str = modes_string; - mode_bits = 0; + flag_bits = 0; + + if (num_matched == 7) + { + str = flags_string; do { - if (strncmp (str, "esa", 3) == 0 - && (str[3] == 0 || str[3] == ',')) { - mode_bits |= 1 << S390_OPCODE_ESA; + if (strncmp (str, "optparm", 7) == 0 + && (str[7] == 0 || str[7] == ',')) { + flag_bits |= S390_INSTR_FLAG_OPTPARM; + str += 7; + } else if (strncmp (str, "optparm2", 8) == 0 + && (str[8] == 0 || str[8] == ',')) { + flag_bits |= S390_INSTR_FLAG_OPTPARM2; + str += 8; + } else if (strncmp (str, "htm", 3) == 0 + && (str[3] == 0 || str[3] == ',')) { + flag_bits |= S390_INSTR_FLAG_HTM; str += 3; - } else if (strncmp (str, "zarch", 5) == 0 - && (str[5] == 0 || str[5] == ',')) { - mode_bits |= 1 << S390_OPCODE_ZARCH; - str += 5; + } else if (strncmp (str, "vx", 2) == 0 + && (str[2] == 0 || str[2] == ',')) { + flag_bits |= S390_INSTR_FLAG_VX; + str += 2; } else { - fprintf (stderr, "Couldn't parse modes string %s\n", - modes_string); + fprintf (stderr, "Couldn't parse flags string %s\n", + flags_string); exit (1); } if (*str == ',') str++; } while (*str != 0); - - insertExpandedMnemonic (opcode, mnemonic, format, min_cpu, mode_bits); } - else - fprintf (stderr, "Couldn't scan line %s\n", currentLine); + insertExpandedMnemonic (opcode, mnemonic, format, min_cpu, mode_bits, flag_bits); } dumpTable ();