Home | History | Annotate | Line # | Download | only in gspa
      1 /*	$NetBSD: gsp_pseu.c,v 1.3 2001/06/13 10:46:06 wiz Exp $	*/
      2 /*
      3  * GSP assembler - assembler directives
      4  *
      5  * Copyright (c) 1993 Paul Mackerras.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *      This product includes software developed by Paul Mackerras.
     19  * 4. The name of the author may not be used to endorse or promote products
     20  *    derived from this software without specific prior written permission
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 #include <sys/cdefs.h>
     35 #ifndef lint
     36 __RCSID("$NetBSD: gsp_pseu.c,v 1.3 2001/06/13 10:46:06 wiz Exp $");
     37 #endif
     38 
     39 #include "gsp_ass.h"
     40 #include "gsp_code.h"
     41 
     42 extern unsigned highest_pc, line_pc;
     43 
     44 void
     45 pseudo(int code, operand ops)
     46 {
     47 	operand o;
     48 	int32_t val;
     49 	unsigned ln;
     50 	u_int16_t words[2];
     51 
     52 	switch( code ){
     53 	case ORG:
     54 		if( ops == NULL )
     55 			break;
     56 		if( ops->type != EXPR ){
     57 			perr("Inappropriate operand");
     58 			break;
     59 		}
     60 		if( !eval_expr(ops->op_u.value, &val, &ln) ){
     61 			p1err("ORG operand must be defined on pass 1");
     62 			break;
     63 		}
     64 		if( pc > highest_pc )
     65 			highest_pc = pc;
     66 		line_pc = pc = val;
     67 		do_list_pc();
     68 		break;
     69 #ifdef EQU
     70 	case EQU:
     71 		if( label == NULL ){
     72 			perr("Label required");
     73 			break;
     74 		}
     75 		if( ops == NULL )
     76 			break;
     77 		if( ops->type != EXPR ){
     78 			perr("Inappropriate operand");
     79 			break;
     80 		}
     81 		do_asg(label, ops->op_u.value, 0);
     82 		break;
     83 #endif /* EQU */
     84 	case WORD:
     85 	case LONG:
     86 		if( ops == NULL )
     87 			break;
     88 		for( o = ops; o != NULL; o = o->next ){
     89 			if( o->type != EXPR ){
     90 				perr("Inappropriate operand");
     91 				continue;
     92 			}
     93 			if( pass2 ){
     94 				eval_expr(o->op_u.value, &val, &ln);
     95 				words[0] = val;
     96 				if( code == LONG ){
     97 					words[1] = val >> 16;
     98 					putcode(words, 2);
     99 				} else {
    100 					if( val < -32768 || val > 65535 )
    101 						perr("Word value too large");
    102 					putcode(words, 1);
    103 				}
    104 			} else
    105 				pc += code == LONG? 0x20: 0x10;
    106 		}
    107 		return;
    108 	case INCL:
    109 		if( ops == NULL )
    110 			break;
    111 		if( ops->type != STR_OPN ){
    112 			perr("Require filename string");
    113 			break;
    114 		}
    115 		push_input(ops->op_u.string);
    116 		break;
    117 	case BLKB:
    118 	case BLKW:
    119 	case BLKL:
    120 		if( ops == NULL )
    121 			break;
    122 		if( ops->type != EXPR ){
    123 			perr("Inappropriate operand");
    124 			break;
    125 		}
    126 		if( !eval_expr(ops->op_u.value, &val, &ln) ){
    127 			p1err(".BLK%c operand must be defined on pass 1",
    128 				code==BLKB? 'B': code==BLKW? 'W': 'L');
    129 			break;
    130 		}
    131 		val *= 8;
    132 		if( code == BLKB )
    133 			val = (val + 8) & ~15;	/* round to word */
    134 		else
    135 			val *= (code==BLKW? 2: 4);
    136 		pc += val;
    137 		do_list_pc();
    138 		break;
    139 	case START:
    140 		if( !pass2 || ops == NULL )
    141 			break;
    142 		if( ops->type != EXPR ){
    143 			perr("Inappropriate operand");
    144 			break;
    145 		}
    146 		eval_expr(ops->op_u.value, &val, &ln);
    147 		start_at(val);
    148 		do_show_val(val);
    149 		break;
    150 	}
    151 	if( ops == NULL )
    152 		perr("Insufficient operands");
    153 	else if( ops->next != NULL )
    154 		perr("Extra operands ignored");
    155 }
    156