1#include "hppa-opcode.h" 2#include <stdio.h> 3 4extern uint32_t random(); 5 6#define RANGE(number) (random() % (number)) 7#define COIN (RANGE(2)) 8#define IMM_NUM(range) { int tmp000111000usv = RANGE(range); \ 9 if (tmp000111000usv == 0) \ 10 printf(" %d", tmp000111000usv); \ 11 else \ 12 printf(" %c%d", (COIN) ? '-' : ' ', \ 13 tmp000111000usv); \ 14 } 15 16 17/* The 'cond' decode table */ 18 19typedef struct condition_decode { 20 char condition[4]; 21} condT; 22 23char *get_cond_str(const condT table[8][2], int c, int f ); 24 25/* condition decode tables 26 * Refer to PA-RISC 1.1 Architecture and Instruction Set 27 * Reference Manual, Second edition, Sep. 1992, pp. 5-2 - 5-8. 28 */ 29 30/* Note : In all the following tables 31 * "" ... never 32 * "???" ... Invalid combination 33 */ 34 35/* compare/subtraclt instruction conditions */ 36const condT c_comp_sub[8][2] = { /* Table 5-3 */ 37 { "", "TR" }, 38 { "=", "<>" }, 39 { "<", ">=" }, 40 { "<=", ">" }, 41 { "<<", ">>=" }, 42 { "<<=", ">>" }, 43 { "SV", "NSV" }, 44 { "OD", "EV" } 45}; 46 47/* add instruction conditions */ 48const condT c_add[8][2] = { /* Table 5-4 */ 49 { "", "TR" }, 50 { "=", "<>" }, 51 { "<", ">=" }, 52 { "<=", ">" }, 53 { "NUV", "UV" }, 54 { "ZNV", "VNZ" }, 55 { "SV", "NSV" }, 56 { "OD", "EV" } 57}; 58 59/* logical instruction conditions */ 60const condT c_logical[8][2] = { /* Table 5-5 */ 61 { "", "TR" }, 62 { "=", "<>" }, 63 { "<", ">=" }, 64 { "<=", ">" }, 65 { "???", "???" }, 66 { "???", "???" }, 67 { "???", "???" }, 68 { "OD", "EV" } 69}; 70 71/* unit instruction conditions */ 72const condT c_unit[8][2] = { /* Table 5-6 */ 73 { "", "TR" }, 74 { "???", "???" }, 75 { "SBZ", "NBZ" }, 76 { "SHZ", "NHZ" }, 77 { "SDC", "NDC" }, 78 { "???", "???" }, 79 { "SBC", "NBC" }, 80 { "SHC", "NHC" } 81}; 82 83/* shift/extract/deposit instruction conditions */ 84const condT c_shift_extract_deposit[8][2] = { /* Table 5-7 */ 85 { "", "???" }, 86 { "=", "???" }, 87 { "<", "???" }, 88 { "OD", "???" }, 89 { "TR", "???" }, 90 { "<>", "???" }, 91 { ">=", "???" }, 92 { "EV", "???" } 93}; 94 95 96 97char *controlregs[] = { "fir", "psr", "epsr", "dirbase", "db", "fsr" }; 98#define NCREGS (sizeof controlregs / sizeof controlregs[0]) 99 100char *textlabels[] = { "foo", "bar", "baz", "xork" }; 101#define NTLABELS (sizeof textlabels / sizeof textlabels[0]) 102 103char *datalabels[] = { "data1", "data2", "data3", "data4" }; 104#define NDLABELS (sizeof datalabels / sizeof datalabels[0]) 105 106char *fp_cmp_cond[] = { 107 "false?","false", "true?", "true", "!<=>", "!?>=", "!?<=", 108 "!<>", "!>=", "!?>", "?<=", "!<=", "!?<", "?>=", "!?=", 109 "!=t", "<=>", "=t", "?=", "?<", "<=", "!>", "?>", ">=", 110 "!<", "<>", "!=", "!?", "?", "=", "<", ">" 111}; 112#define NFPCOND (sizeof fp_cmp_cond / sizeof fp_cmp_cond[0]) 113 114char *fp_format_str[] = { "sgl", "dbl", "quad" }; 115#define NFPFMT (sizeof fp_format_str / sizeof fp_format_str[0]) 116 117/* 118 * Traverse the opcode table, dumping out sample instructions. 119 */ 120void 121main() 122{ 123 int i; 124 const char *arg; 125 int do_not_nullify = 0; 126 127 printf( "\t.text\n%s:", textlabels[0] ); 128 /* a label at the begining of the file */ 129 printf("label1:\n"); 130 131 for ( i = 0; i < NUMOPCODES; ++i ) 132 { 133 if ( i == (NUMOPCODES/3) ) 134 printf( "%s:", textlabels[1] ); 135 if ( i == (NUMOPCODES/2) ) 136 printf( "%s:", textlabels[2] ); 137 138 printf( "\t%s", pa_opcodes[i].name ); 139 140 for ( arg = pa_opcodes[i].args; *arg != '\0'; ++arg ) 141 { 142 switch( *arg ) { 143 144 case '\0': /* end of args */ 145 break; 146 147 case '(': /* these must match exactly */ 148 putchar(' '); /* and FALLTHRU */ 149 case ')': 150 case ',': 151 case ' ': 152 putchar(*arg); 153 break; 154 155 case 'b': /* 5 bit register field at 10 */ 156 case 'x': /* 5 bit register field at 15 */ 157 case 't': /* 5 bit register field at 31 */ 158 case 'v': /* a 't' type extended to handle L/R register halves. */ 159 case 'E': /* a 'b' type extended to handle L/R register halves. */ 160 case 'X': /* an 'x' type extended to handle L/R register halves. */ 161 case '4': /* 5 bit register field at 10 (used in 'fmpyadd' and 'fmpysub') */ 162 case '6': /* 5 bit register field at 15 (used in 'fmpyadd' and 'fmpysub') */ 163 case '7': /* 5 bit register field at 31 (used in 'fmpyadd' and 'fmpysub') */ 164 case '8': /* 5 bit register field at 20 (used in 'fmpyadd' and 'fmpysub') */ 165 case '9': /* 5 bit register field at 25 (used in 'fmpyadd' and 'fmpysub') */ 166 printf(" %%r%d", RANGE(32)); 167 break; 168 169 case 'r': /* 5 bit immediate at 31 */ 170 case 'R': /* 5 bit immediate at 15 */ 171 printf(" %d", RANGE(32)); 172 break; 173 case 'T': /* 5 bit field length at 31 (encoded as 32-T) */ 174 printf(" %d", RANGE(31) + 1); 175 break; 176 177 case '5': /* 5 bit immediate at 15 */ 178 case 'V': /* 5 bit immediate at 31 */ 179 case 'p': /* 5 bit shift count at 26 (to support SHD instr.) */ 180 /* value is encoded in instr. as 31-p where p is */ 181 /* the value scanned here */ 182 case 'P': /* 5-bit bit position at 26 */ 183 case 'Q': /* 5 bit immediate at 10 (unsigned bit position */ 184 /* value for the bb instruction) */ 185 IMM_NUM(15); 186 continue; 187 188 case 's': /* 2 bit space identifier at 17 */ 189 printf(" %d", RANGE(4)); 190 break; 191 192 case 'S': /* 3 bit space identifier at 18 */ 193 printf(" %%sr%d", RANGE(8)); 194 break; 195 196 case 'c': /* indexed load completer. */ 197 { 198 int m, u, i; 199 200 m = COIN; 201 u = COIN; 202 i = 0; 203 if (COIN) 204 while (i < 2) { 205 if (m==1 && u==1) { 206 printf(",sm"); 207 i++; 208 } 209 else if (m==1) 210 printf(",m"); 211 else if (u==1) 212 printf(",s"); 213 else /* m==0 && u==0 */ { 214 printf(",sm"); 215 i++; 216 } /* probability distribution */ 217 i++; 218 } 219 continue; 220 } 221 case 'C': /* short load and store completer */ 222 if (COIN) 223 if (COIN) 224 printf(",mb"); 225 else 226 printf(",ma"); 227 continue; 228 case 'Y': /* Store Bytes Short completer */ 229 { 230 int i = 0, m, a; 231 while ( i < 2 ) { 232 m = COIN; 233 a = COIN; 234 235 if (m==1) /* && (a==0 || a==1) */ 236 printf(",m"); 237 else if (a==0) /* && m==0 */ 238 printf(",b"); 239 else if (a==1) /* && m==0 */ 240 printf(",e"); 241 i++; 242 } 243 continue; 244 } 245 case '<': /* non-negated compare/subtract conditions. */ 246 { 247 int cmpltr; 248 249 do { 250 cmpltr = RANGE(4); 251 } while (cmpltr == 0); 252 253 printf(",%s", get_cond_str(c_comp_sub, cmpltr, 0)); 254 } 255 continue; 256 case '?': /* negated or non-negated cmp/sub conditions. */ 257 /* used only by ``comb'' and ``comib'' pseudo-ops */ 258 case '-': /* compare/subtract conditions */ 259 { 260 int flag, cmpltr; 261 char *tmp; 262 263 do { 264 flag = COIN; 265 cmpltr = RANGE(8); 266 } while ((flag & cmpltr) == 0 || (cmpltr == 0)); 267 268 tmp = get_cond_str(c_comp_sub, cmpltr, flag); 269 270 if (*tmp != '\0') 271 printf(",%s", tmp); 272 } 273 continue; 274 case '+': /* non-negated add conditions */ 275 case '!': /* negated or non-negated add conditions. */ 276 { 277 int flag, cmpltr; 278 char *tmp; 279 280 do { 281 flag = COIN; 282 cmpltr = RANGE(8); 283 } while ((flag & cmpltr) == 0 || (cmpltr == 0)); 284 285 tmp = get_cond_str(c_add, cmpltr, flag); 286 287 if (COIN && (*tmp != '\0')) /* condition */ { 288 printf(",%s", tmp); 289 if (COIN) { /* nullify */ 290 printf(",n "); 291 do_not_nullify = 1; 292 } 293 } 294 } 295 continue; 296 case '&': /* logical instruction conditions */ 297 { 298 int flag, cmpltr; 299 char *tmp; 300 301 flag = COIN; 302 do { 303 cmpltr = RANGE(8); 304 } while (cmpltr == 4 || cmpltr == 5 || cmpltr == 6); 305 306 tmp = get_cond_str(c_logical, cmpltr, flag); 307 308 if (COIN && (*tmp != '\0')) /* condition */ 309 printf(",%s", tmp); 310 } 311 continue; 312 case 'U': /* unit instruction conditions */ 313 { 314 int flag, cmpltr; 315 char *tmp; 316 317 flag = COIN; 318 do { 319 cmpltr = RANGE(8); 320 } while (cmpltr == 1 || cmpltr == 5); 321 322 tmp = get_cond_str(c_unit, cmpltr, flag); 323 if (COIN && (*tmp != '\0')) /* condition */ 324 printf(",%s", tmp); 325 } 326 continue; 327 case '>': /* shift/extract/deposit conditions. */ 328 { 329 int cmpltr; 330 char *tmp; 331 332 cmpltr = RANGE(8); 333 334 tmp = get_cond_str(c_shift_extract_deposit, cmpltr, 0); 335 336 if (COIN && (*tmp != '\0')) /* condition */ 337 printf(",%s", tmp); 338 } 339 continue; 340 case '~': /* bvb,bb conditions */ 341 if (COIN) 342 printf(",<"); 343 else 344 printf(",>="); 345 continue; 346 347 case 'i': /* 11 bit immediate at 31 */ 348 IMM_NUM(1024); 349 continue; 350 351 case 'j': /* 14 bit immediate at 31 --- LO14 */ 352 case 'a': /* for be, ble --- BR17*/ 353 { 354 int field_selector = RANGE(3); 355 switch (field_selector) { 356 case 2: /* field selector R`*/ 357 printf(" R`"); 358 break; 359 case 1: /* field selector L`*/ 360 printf(" L`"); 361 break; 362 default: 363 break; 364 } 365 IMM_NUM(8192); 366 continue; 367 } 368 case 'k': /* 21 bit immediate at 31 --- HI21 */ 369 { 370 int field_selector = RANGE(3); 371 switch (field_selector) { 372 case 2: /* field selector R`*/ 373 printf(" R`"); 374 break; 375 case 1: /* field selector L`*/ 376 printf(" L`"); 377 break; 378 default: 379 break; 380 } 381 IMM_NUM(1048576); 382 continue; 383 } 384 case 'n': /* nullification for branch instructions */ 385 if (!do_not_nullify) 386 if (COIN) 387 printf(",n"); 388 else 389 do_not_nullify = 0; 390 continue; 391 case 'w': /* 12 bit branch displacement */ 392 IMM_NUM(2048); 393 continue; 394 case 'W': /* 17 bit branch displacement --- BL17 */ 395 case '@': /* 17 bit branch displacement --- JBSR */ 396 case 'z': /* 17 bit branch displacement (non-pc-relative) */ 397 IMM_NUM(65536); 398 continue; 399 case 'B': /* either "s,b" or "b" where b & s are defined above */ 400 if (COIN) 401 printf(" %d,", RANGE(4)); 402 printf(" %%r%d", RANGE(32)); 403 break; 404 case 'A': /* 13 bit immediate at 18 (to support BREAK instr.) */ 405 printf(" %d", RANGE(4096)); 406 continue; 407 case 'Z': /* System Control Completer(for LDA, LHA, etc.) */ 408 if (COIN) 409 printf(",M"); 410 continue; 411 case 'D': /* 26 bit immediate at 31 (to support DIAG instr.) */ 412 /* the action (and interpretation of this operand is 413 implementation dependent) */ 414 IMM_NUM(33554432); 415 continue; 416 case 'f': /* 3 bit Special Function Unit (SFU) identifier at 25 */ 417 case 'u': /* 3 bit coprocessor unit identifier at 25 */ 418 printf("%d", RANGE(8)); 419 continue; 420 case 'O': /* 20 bit SFU op. split between 15 bits at 20 and 5 bits at 31 */ 421 printf("%d", RANGE(1048576)); 422 continue; 423 case 'o': /* 15 bit Special Function Unit operation at 20 */ 424 case '1': /* 15 bit SFU op. split between 10 bits at 20 425 and 5 bits at 31 */ 426 printf("%d", RANGE(32768)); 427 continue; 428 case '2': /* 22 bit SFU op. split between 17 bits at 20 429 and 5 bits at 31 */ 430 printf("%d", RANGE(4194304)); 431 continue; 432 case '0': /* 10 bit SFU op. split between 5 bits at 20 433 and 5 bits at 31 */ 434 printf("%d", RANGE(1024)); 435 continue; 436 case 'G': /* Destination FP Operand Format Completer (2 bits at 18) */ 437 case 'F': /* Source FP Operand Format Completer (2 bits at 20) */ 438 printf(",%s", fp_format_str[RANGE(NFPFMT)]); 439 continue; 440 case 'M': /* FP Compare Conditions (encoded as 5 bits at 31) */ 441 printf(",%s", fp_cmp_cond[RANGE(NFPCOND)]); 442 continue; 443 444#if 0 445 case 'H': /* Floating Point Operand Format at 26 for */ 446 /* 'fmpyadd' and 'fmpysub' (very similar to 'F') */ 447 /* bits are switched from other FP Operand */ 448 /* formats. 1=SGL, 1=<none>, 0=DBL */ 449 f = pa_parse_fp_format(&s); 450 switch (f) { 451 case SGL: 452 opcode |= 0x20; 453 case DBL: 454 the_insn.fpof1 = f; 455 continue; 456 457 case QUAD: 458 case ILLEGAL_FMT: 459 default: 460 as_bad("Illegal Floating Point Operand Format for" 461 "this instruction: '%s'",*s); 462 } 463 break; 464 default: 465 abort(); 466#endif /* 0 */ 467 468 } 469 } 470 putchar( '\n' ); 471 } 472 /* a label at the end of the file */ 473 printf("label2:\n"); 474 475 476 printf( "%s:\n", textlabels[3] ); 477 printf( "\t.data\n" ); 478 printf( "data1: .space 1024\n" ); 479 printf( "data2: .space 1024\n" ); 480 printf( "data3: .space 1024\n" ); 481 printf( "data4: .space 1024\n" ); 482 483} 484 485/* The function to search the condition decode table 486 * and return the 'cond' 487 * The way tables are initialised ... NULL termination 488 * of 'cond' is assured. 489 */ 490char *get_cond_str(const condT table[8][2], int c, int f ) 491{ 492 493/* do range check and return NULL if out of bound */ 494/* char *str; 495 if ( c < 0 || c > 7 ) 496 *str = (char *) NULL; 497 else if ( f < 0 || f > 1 ) 498 *str = (char *) NULL; 499 else 500 str = table[c][f].condition; 501 502 return str; 503*/ 504 505/* here goes the one liner */ 506 507 return (c<0 || c>7 || f<0 || f>1) 508 ? (char *)NULL : table[c][f].condition ; 509} /* end get_cond_str() */ 510 511