diff options
author | Andreas Krebbel <Andreas.Krebbel@de.ibm.com> | 2007-08-21 15:54:30 +0000 |
---|---|---|
committer | Andreas Krebbel <Andreas.Krebbel@de.ibm.com> | 2007-08-21 15:54:30 +0000 |
commit | ab9c1d86b02edacf18de44cd010d670277df29f3 (patch) | |
tree | 6dc485ac5912b3bda0bd855e4d7c04628f4d75c2 /opcodes/s390-mkopc.c | |
parent | f91828d464fc1a38d635d26b068713e426520157 (diff) | |
download | gdb-ab9c1d86b02edacf18de44cd010d670277df29f3.tar.gz |
2007-08-21 Andreas Krebbel <krebbel1@de.ibm.com>
* s390-mkopc.c (struct s390_cond_ext_format): New global struct.
(s390_cond_ext_format): New global variable.
(expandConditionalJump): New function.
(main): Invoke expandConditionalJump for mnemonics containing '*'.
* s390-opc.txt: Replace mnemonics with conditional
mask extensions with instructions using the newly introduced '*' tag.
Diffstat (limited to 'opcodes/s390-mkopc.c')
-rw-r--r-- | opcodes/s390-mkopc.c | 124 |
1 files changed, 123 insertions, 1 deletions
diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c index e6dc30553c3..64615073d1b 100644 --- a/opcodes/s390-mkopc.c +++ b/opcodes/s390-mkopc.c @@ -115,6 +115,123 @@ insertOpcode (char *opcode, char *mnemonic, char *format, no_ops++; } +struct s390_cond_ext_format +{ + char nibble; + char extension[4]; +}; + +#define NUM_COND_EXTENSIONS 20 + +const struct s390_cond_ext_format s390_cond_extensions[NUM_COND_EXTENSIONS] = + { + { '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 */ + }; + +/* As with insertOpcode instructions are added to the sorted opcode + array. Additionally mnemonics containing the '*<number>' tag are + expanded to the set of conditional instructions described by + s390_cond_extensions with the '*<number>' tag replaced by the + respective mnemonic extensions. */ + +static void +expandConditionalJump (char *opcode, char *mnemonic, char *format, + int min_cpu, int mode_bits) +{ + char prefix[5]; + char suffix[5]; + char number[5]; + int mask_start, i = 0, star_found = 0, reading_number = 0; + int number_p = 0, suffix_p = 0, prefix_p = 0; + + while (mnemonic[i] != '\0') + { + switch (mnemonic[i]) + { + case '*': + if (star_found) + goto malformed_mnemonic; + + star_found = 1; + reading_number = 1; + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (!star_found || !reading_number) + goto malformed_mnemonic; + + number[number_p++] = mnemonic[i]; + break; + + default: + if (reading_number) + { + if (!number_p) + goto malformed_mnemonic; + else + reading_number = 0; + } + + if (star_found) + suffix[suffix_p++] = mnemonic[i]; + else + prefix[prefix_p++] = mnemonic[i]; + } + i++; + } + + prefix[prefix_p] = '\0'; + suffix[suffix_p] = '\0'; + number[number_p] = '\0'; + + if (sscanf (number, "%d", &mask_start) != 1) + goto malformed_mnemonic; + + if (mask_start & 3) + { + fprintf (stderr, "Conditional mask not at nibble boundary in: %s\n", + mnemonic); + return; + } + + mask_start >>= 2; + + for (i = 0; i < NUM_COND_EXTENSIONS; i++) + { + char new_mnemonic[15]; + + strcpy (new_mnemonic, prefix); + strcat (new_mnemonic, s390_cond_extensions[i].extension); + strcat (new_mnemonic, suffix); + opcode[mask_start] = s390_cond_extensions[i].nibble; + insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits); + } + return; + + malformed_mnemonic: + fprintf (stderr, "Malformed mnemonic: %s\n", mnemonic); +} + static char file_header[] = "/* The opcode table. This file was generated by s390-mkopc.\n\n" " The format of the opcode table is:\n\n" @@ -225,7 +342,12 @@ main (void) if (*str == ',') str++; } while (*str != 0); - insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits); + + if (!strchr (mnemonic, '*')) + insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits); + else + expandConditionalJump (opcode, mnemonic, format, + min_cpu, mode_bits); } else fprintf (stderr, "Couldn't scan line %s\n", currentLine); |