2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 #define RCSID5 "$Id: mach5.c,v 0.4 1994/06/24 13:56:30 ceriel Exp $"
9 { oprtype[ operand ] = type; }
15 while ( (s>>=1) != 0 ) twopower++;
22 { mode = modetbl[ twolog( oprtype[opr] ) ] << 12; }
25 chtype( opr, typerange )
28 /* Check type of 'opr' with given 'typerange' and
29 ** set the global var 'mode'.
31 { if ( (oprtype[opr] & typerange) != oprtype[opr] ) argerr();
32 else /* We have a permitted type for 'opr'. */ setmode( opr );
39 case 0xB10A: case 0x1B00: case 0x1900:
40 /* R32 expected */ if (reg & 1) regerr(); break;
41 case 0xB107: case 0x1A00: case 0x1800:
42 /* R64 expected */ if (reg & 3) regerr(); break;
46 ATYPE checkaddr( addr )
48 /* Called by functions emit_ad() and branch(). */
51 addr_struct.seg = addr >> 16;
52 addr_struct.off = addr & 0xFFFF;
53 if ( addr_struct.seg < 0 ) addr_struct.seg = 0;
55 else fit(fit7(addr_struct.seg));
57 return( addr_struct );
62 /* When the type of an operand is 'da' or 'x' this function
67 addr = checkaddr( ad_inf.val );
68 /* Always the long format is emitted, because the binary
69 ** will be downloaded into one z8000-segment with offset
70 ** 0x0000 upto 0xFFFF,so the chance we can use the short
71 ** format is very small.
73 emit2( 1<<15 | addr.seg<<8 );
74 emit2( addr.off ); /* ??? relocation information ??? */
78 ldmcode( wrd1, wrd2, num )
82 emit2( wrd2<<8 | num-1 );
83 if ( mode>>12 == 4 ) emit_ad( addr_inf );
87 valu_t adjust( absval )
89 { valu_t val = absval - DOTVAL - 2;
91 if ( pass == PASS_2 && val > 0 ) val -= DOTGAIN;
99 /* This routine determines for the F3 format instructions whether the
100 ** relative address is small enough to fit in normal code; If this is
101 ** so normal code is emitted otherwise 'long' code is emitted contai-
102 ** ning the direct address.
104 { int longopc = 0, reladdr = 0, sm2, sm4;
108 val = adjust(exp.val) >> 1;
109 if ( (exp.typ & ~S_DOT) != DOTTYP ) sm2 = sm4 = 0;
111 { switch ( opc & 0xF000 )
112 { case DJNZ_: sm2 = fit7( -val );
115 case JR_: sm2 = fits8( val );
116 reladdr = low8( val );
117 longopc = 0x5E00 | (opc>>8 & 0xF);
119 case CALR_: sm2 = fits12( -val );
120 reladdr = low12( -val );
124 sm4 = sm2 || fit8( (int)exp.val );
126 switch ( opc & 0xF000 )
127 { case DJNZ_: fit( sm2 ); /* djnz must be short */
128 emit2( opc | reladdr );
130 case JR_: case CALR_:
133 if ( sm2 ) emit2( opc | reladdr );
134 else /* replace by jp/call da */
136 addr = checkaddr( exp.val );
137 if ( sm4 ) /* short-offset */
138 emit2( addr.seg<<8 | addr.off );
140 { emit2( 1<<15 | addr.seg<<8 );
151 /* This routine determines for the F4 format instructions whether the
152 ** address is within the same segment (meaning a relative address of
153 ** less than 16 bits); If this is so normal code is emitted otherwise
154 ** an error message is given.
156 { if ( pass >= PASS_2 && (exp.typ & ~S_DOT) != DOTTYP )
157 serror( "relative too far" );
159 emit2( (int)adjust(exp.val) );
165 { switch( w1 & 0x0F04 )
166 { /* Remember: w2 negative means right shift ! */
167 case 0x200: /*byte*/ fit( w2>=-8 && w2<=8 ); break;
168 case 0x300: /*word*/ fit( w2>=-16 && w2<=16 ); break;
169 case 0x304: /*long*/ fit( w2>=-32 && w2<=32 ); break;
177 { serror( "illegal operand" ); }