123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- #include <ctype.h>
- #include "as.h"
- #define DOLLAR '$'
- #define LEFT '('
- #define RIGHT ')'
- /*****************************************************************************/
- /* Een constraint-function */
- cst( arg)
- struct t_operand *arg;
- {
- return( arg->type == CONST);
- }
- /*****************************************************************************/
- /* decode_operand() recognizes the follwing assembly-argumnets:
-
- $cst : CONST
- register : REGISTER
- -(register) : AUTO_DEC
- (register)+ : AUTO_INC
- (register) : REG_DEF
- indx(register) : IND_REG
- label+offset : LABEL
- label[b|f] : L_ILB
- */
- /* An assembly instruction has at most 5 arguments.
- * This is for the time being.
- */
- char lab_buf[4][256],
- ind_buf[4][256],
- *match(), *lab(), *ind(), *end_arg(), *strchr();
- static int n_index = -1;
- process_label( l)
- char *l;
- {
- }
- process_mnemonic( m)
- char *m;
- {
- }
- process_operand( arg, op)
- register char *arg;
- register struct t_operand *op;
- {
- register char *einde;
- if ( n_index == 3)
- n_index = 0;
- else
- n_index++;
- if ( arg[0] == '~' ) {
- op->type = CONST;
- op->cst = arg+1;
- }
- else if ( is_reg( arg, &(op->num)) ) {
- op->type = REGISTER;
- }
- else if ((arg[0]=='-') && (arg[1] == LEFT) &&
- is_reg( arg+2,&(op->num))) {
- op->type = AUTO_DEC;
- }
- else if( ( arg[0] == LEFT) && is_reg( arg+1, &(op->num))) {
- arg = match( arg, RIGHT);
- if ( *(arg+1) == '+')
- op->type = AUTO_INC;
- else
- op->type = REG_DEF;
- }
- else {
- einde = end_arg( arg);
- if ( (*einde == 'b' || *einde == 'f') && isdigit( *(einde-1))) {
- *einde = '\0';
- op->type = L_ILB;
- op->offset = "0";
- op->lab = arg;
- }
- else if ( *einde == RIGHT) {
- op->type = IND_REG;
- arg = ind( ind_buf[ n_index], arg);
- if ( is_reg( arg+1, &(op->num)))
- op->indx = ind_buf[ n_index];
- else
- fprint( STDERR, "unknown argtype %s\n", arg);
- }
- else {
- op->type = LABEL;
- arg = lab( lab_buf[ n_index], arg);
- op->lab = lab_buf[ n_index];
- if ( *arg == '\0')
- op->offset = "0";
- else
- op->offset = arg+1;
- }
- }
- }
- char *ind( buf, str)
- register char *buf, *str;
- /* Reads the index in front of '(register)'.
- */
- {
- while ( *str != LEFT)
- *buf++ = *str++;
- *buf = '\0';
- return( str);
- }
- char *lab( buf, str)
- register char *buf, *str;
- /* Reads 'label' in front of '+offset'.
- */
- {
- while ( ( *str != '+') && ( *str != '\0'))
- *buf++ = *str++;
- *buf = '\0';
- while ( isspace( *(buf-1)) ) {
- *(buf-1) = '\0';
- buf--;
- }
- return( str);
- }
-
- int is_reg( str, num)
- register char *str;
- register int *num;
- /* Is "str" a 'registers' ?
- */
- {
- if ( ( *str == 'a') && ( *(str+1) == 'p')) {
- *num = 12;
- return( TRUE);
- }
- else if ( ( *str == 'f') && ( *(str+1) == 'p')) {
- *num = 13;
- return( TRUE);
- }
- else if ( ( *str == 's') && ( *(str+1) == 'p')) {
- *num = 14;
- return( TRUE);
- }
- if ( *str == 'r') {
- if ( isdigit( *(str+1)) && isdigit( *(str+2))) {
- *num = ( *(str+1) - '0') * 10 + *(str+2) - '0';
- return( TRUE);
- }
- else if ( isdigit( *(str+1))) {
- *num = *(str+1) - '0';
- return( TRUE);
- }
- else
- return( FALSE);
- }
- return( FALSE);
- }
- char *end_arg( str)
- register char *str;
- /* Shift to the last character of "str".
- */
- {
- while ( *str != '\0')
- str++;
- return( str-1);
- }
- char *match( str, sym)
- register char *str;
- char sym;
- {
- while ( *str != sym)
- str++;
- return( str);
- }
- /******************************************************************************/
- char my_buf[256];
- gen_operand( op)
- register struct t_operand *op;
- /* Generate object-code for a argument.
- */
- {
- switch( op->type) {
- case CONST :
- if (isdigit(op->cst[0])) {
- long l, atol();
- l = atol(op->cst);
- if (fit_6bits(l)) {
- @text1(%$(op->cst));
- }
- else {
- @text1( 0x8f);
- @text4( %$(op->cst));
- }
- }
- else {
- @__as_const(%$(op->cst));
- }
- break;
- case REGISTER: @text1( %d(0x50 | op->num));
- break;
- case REG_DEF : @text1( %d(0x60 | op->num));
- break;
- case AUTO_DEC : @text1( %d(0x70 | op->num));
- break;
- case AUTO_INC : @text1( %d(0x80 | op->num));
- break;
- case IND_REG :
- if (isdigit(op->indx[0])) {
- long l, atol();
- l = atol(op->indx);
- if (fit_byte(l)) {
- @text1( %d(0xa0 | op->num));
- @text1( %$(op->indx));
- } else if (fit_word(l)) {
- @text1( %d(0xc0 | op->num));
- @text2( %$(op->indx));
- } else {
- @text1( %d(0xe0 | op->num));
- @text4( %$(op->indx));
- }
- }
- else {
- @__as_indexed(%$(op->indx) , %d(op->num));
- }
- break;
- case LABEL : @text1( 0xef);
- if ( strchr( op->lab, DOLLAR)) {
- @reloc4( %$(op->lab), %$(op->offset), PC_REL);
- }
- else if ( strchr( op->lab, LEFT)) {
- @reloc4( %$(op->lab), %$(op->offset), PC_REL);
- }
- else {
- sprint( my_buf, "\"%s\"", op->lab);
- @reloc4( %$(my_buf), %$(op->offset) , PC_REL);
- }
- break;
- case L_ILB : @text1( %dist( op->lab));
- break;
- default : fprint( STDERR, "error");
- }
- }
|