* @(#)kdb_opset.c 7.3 (Berkeley) 5/26/88
"p1lr", &pcb
.pcb_p1lr
, "p1br", (int *)&pcb
.pcb_p1br
,
"p0lr", &pcb
.pcb_p0lr
, "p0br", (int *)&pcb
.pcb_p0br
,
"ksp", &pcb
.pcb_ksp
, "esp", &pcb
.pcb_esp
,
"ssp", &pcb
.pcb_ssp
, "psl", &pcb
.pcb_psl
,
"pc", &pcb
.pcb_pc
, "usp", &pcb
.pcb_usp
,
"fp", &pcb
.pcb_fp
, "ap", &pcb
.pcb_ap
,
"r11", &pcb
.pcb_r11
, "r10", &pcb
.pcb_r10
,
"r9", &pcb
.pcb_r9
, "r8", &pcb
.pcb_r8
,
"r7", &pcb
.pcb_r7
, "r6", &pcb
.pcb_r6
,
"r5", &pcb
.pcb_r5
, "r4", &pcb
.pcb_r4
,
"r3", &pcb
.pcb_r3
, "r2", &pcb
.pcb_r2
,
"r1", &pcb
.pcb_r1
, "r0", &pcb
.pcb_r0
,
* If you change these definitions, you must also change the tables
#define TYPB 000 /* byte integer */
#define TYPW 001 /* word integer */
#define TYPL 002 /* long integer */
#define TYPQ 003 /* quad integer */
#define TYPO 004 /* octa integer */
#define TYPF 005 /* F float */
#define TYPD 006 /* D float */
#define TYPG 007 /* G float */
#define TYPH 010 /* H float */
#define TYPUNPACKED 011 /* when unpacked into mantissa & exponent */
#define TYPNONE 012 /* when nothing */
#define TYPLG 4 /* number of bits the above take up */
#define TYPMASK ((1<<TYPLG)-1) /* the mask (assumes 2's comp arith) */
* Constructors and extractors for argument access kinds and types
#define A_CONS(access, type) ((access) | (type))
#define A_ACCEXT(consed) ((consed) & (TYPMASK << TYPLG))
#define A_TYPEXT(consed) ((consed) & TYPMASK)
* Argument access types used to test validity of operands to operators
#define ACCR (1<<TYPLG) /* read */
#define ACCW (2<<TYPLG) /* write */
#define ACCB (4<<TYPLG) /* branch displacement */
#define ACCA (8<<TYPLG) /* address only */
#define ACCV (8<<TYPLG) /* address only */
#define ACCM (ACCR | ACCW) /* modify */
#define ACCI (ACCB | ACCR) /* XFC code */
#define ACCESSMASK (ACCA | ACCR | ACCW | ACCB) /* the mask */
* Construction of TYPX and ACCX, to make the instrs table
* For real memory address
#define A_AB A_CONS(ACCA, TYPB)
#define A_AW A_CONS(ACCA, TYPW)
#define A_AL A_CONS(ACCA, TYPL)
#define A_AQ A_CONS(ACCA, TYPQ)
#define A_AO A_CONS(ACCA, TYPO)
#define A_AF A_CONS(ACCA, TYPF)
#define A_AD A_CONS(ACCA, TYPD)
#define A_AG A_CONS(ACCA, TYPG)
#define A_AH A_CONS(ACCA, TYPH)
* For real memory addresses, or register addresses [sic]
* CHEAT! we just call these read access, since
* registers are allowed. All field instruction, except insv,
* are are read access fields.
#define A_VB A_CONS(ACCR, TYPB)
#define A_VW A_CONS(ACCR, TYPW)
#define A_VL A_CONS(ACCR, TYPL)
#define A_VQ A_CONS(ACCR, TYPQ)
#define A_VO A_CONS(ACCR, TYPO)
#define A_VF A_CONS(ACCR, TYPF)
#define A_VD A_CONS(ACCR, TYPD)
#define A_VG A_CONS(ACCR, TYPG)
#define A_VH A_CONS(ACCR, TYPH)
* For branch displacement
#define A_BB A_CONS(ACCB, TYPB)
#define A_BW A_CONS(ACCB, TYPW)
#define A_MB A_CONS(ACCM, TYPB)
#define A_MW A_CONS(ACCM, TYPW)
#define A_ML A_CONS(ACCM, TYPL)
#define A_MF A_CONS(ACCM, TYPF)
#define A_MD A_CONS(ACCM, TYPD)
#define A_MG A_CONS(ACCM, TYPG)
#define A_MH A_CONS(ACCM, TYPH)
#define A_RB A_CONS(ACCR, TYPB)
#define A_RW A_CONS(ACCR, TYPW)
#define A_RL A_CONS(ACCR, TYPL)
#define A_RQ A_CONS(ACCR, TYPQ)
#define A_RO A_CONS(ACCR, TYPO)
#define A_RF A_CONS(ACCR, TYPF)
#define A_RD A_CONS(ACCR, TYPD)
#define A_RG A_CONS(ACCR, TYPG)
#define A_RH A_CONS(ACCR, TYPH)
#define A_WB A_CONS(ACCW, TYPB)
#define A_WW A_CONS(ACCW, TYPW)
#define A_WL A_CONS(ACCW, TYPL)
#define A_WQ A_CONS(ACCW, TYPQ)
#define A_WO A_CONS(ACCW, TYPO)
#define A_WF A_CONS(ACCW, TYPF)
#define A_WD A_CONS(ACCW, TYPD)
#define A_WG A_CONS(ACCW, TYPG)
#define A_WH A_CONS(ACCW, TYPH)
#define OP(name,eopcode,popdcode,nargs,a1,a2,a3,a4,a5,a6) \
{name,eopcode,popdcode,nargs,a1,a2,a3,a4,a5,a6}
* Definitions for the escape bytes
#define mapescbyte(b) ((b) == ESCD ? 1 : (b) == ESCF ? 2 : 0)
static struct insttab insttab
[] = {
#include "../vax/kdb_instrs"
* Convert TYP[BWLQOFDGH] into {1 if relocation not OK}
* Convert TYP[BWLQOFDGH] into {1 ... 16}
static char *regname
[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10","r11","ap", "fp", "sp", "pc"
static char *fltimm
[] = {
"0.5", "0.5625", "0.625", "0.6875", "0.75", "0.8125", "0.875", "0.9375",
"1.0", "1.125", "1.25", "1.375", "1.5", "1.625", "1.75", "1.875",
"2.0", "2.25", "2.5", "2.75", "3.0", "3.25", "3.5", "3.75",
"4.0", "4.5", "5.0", "5.5", "6.0", "6.5", "7.0", "7.5",
"8.0", "9.0", "10.0", "11.0", "12.0", "13.0", "14.0", "15.0",
"16.0", "18.0", "20.0", "22.0", "24.0", "26.0", "28.0", "30.0",
"32.0", "36.0", "40.0", "44.0", "48.0", "52.0", "56.0", "60.0",
"64.0", "72.0", "80.0", "88.0", "96.0", "104.0", "112.0", "120.0"
static int type
, space
, incp
;
static long insoutvar
[36];
* Definitions for registers and for operand classes
static char *insregname(); /* how to print a register */
#define OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF))
#define OC_AMEXT(x) (((x) >> OC_SHIFT) & 0xF)
#define OC_REGEXT(x) ((x) & 0xF)
* Definitions for large numbers
typedef struct as_number
*numberp
;
static numberp
snarfreloc();
* Definitions for special instructions
/* two level 1-based index by opcode into insttab */
static short ioptab
[3][256];
register struct insttab
*p
;
for(p
= insttab
; p
->iname
; p
++){
mapchar
= mapescbyte(p
->eopcode
);
if (ioptab
[mapchar
][p
->popcode
])
ioptab
[mapchar
][p
->popcode
] = (p
- insttab
) + 1;
static u_char
snarfuchar();
* Global variables for communicating with the minions and printins
static short argno
; /* which argument one is working on */
static char insoutfmt
[2]; /* how to format the relocated symbols */
char *indexreg
; /* print of which register indexes */
char *indexed
; /* we indexed */
register struct insttab
*ip
;
if ((mapchar
= mapescbyte(ins
)) != 0){
if (ioptab
[mapchar
][ins2
] == 0){
* Oops; not a defined instruction;
* back over this escape byte.
if (ioptab
[mapchar
][ins
] == 0){
printf("<undefined operator byte>: %x", ins
);
ip
= &insttab
[ioptab
[mapchar
][ins
] - 1];
printf("%s\t", ip
->iname
);
for (ap
= ip
->argtype
, argno
= 0; argno
< ip
->nargs
; argno
++, ap
++) {
savevar(0x80000000); /* an illegal symbol */
if (A_ACCEXT(optype
) & ACCB
){
switch(A_TYPEXT(optype
)){
mode
= OC_CONS(OC_BDISP
, R_PC
);
mode
= OC_CONS(OC_WDISP
, R_PC
);
indexreg
= operandout(mode
, optype
);
casebody(insoutvar
[1], insoutvar
[2]);
struct as_number
*valuep
;
#define OSIZE (sizeof(short))
for (i
= 0; i
<= limit
; i
++) {
printf(" %R: ", i
+ base
);
valuep
= snarfreloc(OSIZE
, 0);
dispaddress(valuep
, OC_CONS(OC_WDISP
, R_PC
));
* magic values to mung an offset to a register into
* something that psymoff can understand.. all magic
static long magic_masks
[5] = {0, 0x80, 0x8000, 0, 0};
static long magic_compl
[5] = {0, 0x100, 0x10000,0, 0};
* Snarf up some bytes, and put in the magic relocation flags
static numberp
snarfreloc(nbytes
)
if (back
->num_ulong
[0] & magic_masks
[nbytes
])
back
->num_ulong
[0] -= magic_compl
[nbytes
];
* The following code is NOT portable from the PDP 11 to the VAX
* because of the byte ordering problem.
static numberp
snarf(nbytes
)
static struct as_number backnumber
;
static struct as_number znumber
; /* init'ed to 0 */
for (i
= 0; i
< nbytes
; i
++)
backnumber
.num_uchar
[i
] = snarfuchar();
* Read one single character, and advance the dot
* assert: bchkget and inkdot don't have side effects
back
= (u_char
)bchkget(inkdot(incp
), idsp
);
* normal operand; return non zero pointer to register
* name if this is an index instruction.
char *operandout(mode
, optype
)
regnumber
= OC_REGEXT(mode
);
r
= insregname(regnumber
);
shortliteral(mode
, optype
);
return(r
); /* will be printed later */
pcimmediate(mode
, optype
);
dispaddress(snarfreloc(nbytes
), mode
);
dispaddress(valuep
, mode
)
int regnumber
= OC_REGEXT(mode
);
/* PC offset addressing */
valuep
->num_ulong
[0] += inkdot(incp
);
psymoff(valuep
->num_ulong
[0], type
, &insoutfmt
[0]);
printf(LPRMODE
, valuep
->num_ulong
[0]);
printf("(%s)", insregname(regnumber
));
savevar((long)valuep
->num_ulong
[0]);
* print out a short literal
shortliteral(mode
, optype
)
switch(A_TYPEXT(optype
)){
printf("$%s", fltimm
[mode
]);
pcimmediate(mode
, optype
)
if (mode
== OC_CONS(OC_DAIREG
, R_PC
)){ /* PC absolute, always 4 bytes*/
dispaddress(snarfreloc(4), mode
);
nbytes
= ty_nbyte
[A_TYPEXT(optype
)];
if (! ty_NORELOC
[A_TYPEXT(optype
)]){
dispaddress(snarfreloc(nbytes
), mode
);
bignumprint(nbytes
, optype
);
bignumprint(nbytes
, optype
)
switch(A_TYPEXT(optype
)){
printf("0f%f", valuep
->num_num
.numFf_float
.Ff_value
);
printf("0d%f", valuep
->num_num
.numFd_float
.Fd_value
);
printf("0g::"); goto qprint
;
printf("0h::"); goto qprint
;
for (bindex
= nbytes
- 1; bindex
>= 0; --bindex
){
for (nindex
= 4; nindex
>= 0; nindex
-= 4){
ch
= (valuep
->num_uchar
[bindex
] >> nindex
);
if ( ! (leading_zero
&= (ch
== 0) ) ){