mach5.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  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".
  4. */
  5. #define RCSID5 "$Id$"
  6. settype( type )
  7. int type;
  8. { oprtype[ operand ] = type; }
  9. int twolog( s )
  10. int s;
  11. { int twopower = 0;
  12. while ( (s>>=1) != 0 ) twopower++;
  13. return( twopower );
  14. }
  15. setmode( opr )
  16. int opr;
  17. { mode = modetbl[ twolog( oprtype[opr] ) ] << 12; }
  18. chtype( opr, typerange )
  19. int opr,
  20. typerange;
  21. /* Check type of 'opr' with given 'typerange' and
  22. ** set the global var 'mode'.
  23. */
  24. { if ( (oprtype[opr] & typerange) != oprtype[opr] ) argerr();
  25. else /* We have a permitted type for 'opr'. */ setmode( opr );
  26. }
  27. chreg( opc, reg )
  28. int opc, reg;
  29. { switch( opc ) {
  30. case 0xB10A: case 0x1B00: case 0x1900:
  31. /* R32 expected */ if (reg & 1) regerr(); break;
  32. case 0xB107: case 0x1A00: case 0x1800:
  33. /* R64 expected */ if (reg & 3) regerr(); break;
  34. }
  35. }
  36. ATYPE checkaddr( addr )
  37. valu_t addr;
  38. /* Called by functions emit_ad() and branch(). */
  39. { ATYPE addr_struct;
  40. addr_struct.seg = addr >> 16;
  41. addr_struct.off = addr & 0xFFFF;
  42. if ( addr_struct.seg < 0 ) addr_struct.seg = 0;
  43. #ifdef ASLD
  44. else fit(fit7(addr_struct.seg));
  45. #endif
  46. return( addr_struct );
  47. }
  48. emit_ad( ad_inf )
  49. expr_t ad_inf;
  50. /* When the type of an operand is 'da' or 'x' this function
  51. ** emits the address.
  52. */
  53. { ATYPE addr;
  54. addr = checkaddr( ad_inf.val );
  55. /* Always the long format is emitted, because the binary
  56. ** will be downloaded into one z8000-segment with offset
  57. ** 0x0000 upto 0xFFFF,so the chance we can use the short
  58. ** format is very small.
  59. */
  60. emit2( 1<<15 | addr.seg<<8 );
  61. emit2( addr.off ); /* ??? relocation information ??? */
  62. }
  63. ldmcode( wrd1, wrd2, num )
  64. int wrd1, wrd2, num;
  65. { fit(fit4(num-1));
  66. emit2( mode | wrd1 );
  67. emit2( wrd2<<8 | num-1 );
  68. if ( mode>>12 == 4 ) emit_ad( addr_inf );
  69. }
  70. valu_t adjust( absval )
  71. valu_t absval;
  72. { valu_t val = absval - DOTVAL - 2;
  73. if ( pass == PASS_2 && val > 0 ) val -= DOTGAIN;
  74. return( val );
  75. }
  76. branch( opc, exp )
  77. int opc;
  78. expr_t exp;
  79. /* This routine determines for the F3 format instructions whether the
  80. ** relative address is small enough to fit in normal code; If this is
  81. ** so normal code is emitted otherwise 'long' code is emitted contai-
  82. ** ning the direct address.
  83. */
  84. { int longopc = 0, reladdr = 0, sm2, sm4;
  85. valu_t val;
  86. ATYPE addr;
  87. val = adjust(exp.val) >> 1;
  88. if ( (exp.typ & ~S_DOT) != DOTTYP ) sm2 = sm4 = 0;
  89. else
  90. { switch ( opc & 0xF000 )
  91. { case DJNZ_: sm2 = fit7( -val );
  92. reladdr = -val;
  93. break;
  94. case JR_: sm2 = fits8( val );
  95. reladdr = low8( val );
  96. longopc = 0x5E00 | (opc>>8 & 0xF);
  97. break;
  98. case CALR_: sm2 = fits12( -val );
  99. reladdr = low12( -val );
  100. longopc = 0x5F00;
  101. break;
  102. }
  103. sm4 = sm2 || fit8( (int)exp.val );
  104. }
  105. switch ( opc & 0xF000 )
  106. { case DJNZ_: fit( sm2 ); /* djnz must be short */
  107. emit2( opc | reladdr );
  108. break;
  109. case JR_: case CALR_:
  110. sm4 = small(sm4, 2);
  111. sm2 = small(sm2, 2);
  112. if ( sm2 ) emit2( opc | reladdr );
  113. else /* replace by jp/call da */
  114. { emit2( longopc );
  115. addr = checkaddr( exp.val );
  116. if ( sm4 ) /* short-offset */
  117. emit2( addr.seg<<8 | addr.off );
  118. else
  119. { emit2( 1<<15 | addr.seg<<8 );
  120. emit2( addr.off );
  121. }
  122. }
  123. }
  124. }
  125. ldrel( opc, exp )
  126. int opc;
  127. expr_t exp;
  128. /* This routine determines for the F4 format instructions whether the
  129. ** address is within the same segment (meaning a relative address of
  130. ** less than 16 bits); If this is so normal code is emitted otherwise
  131. ** an error message is given.
  132. */
  133. { if ( pass >= PASS_2 && (exp.typ & ~S_DOT) != DOTTYP )
  134. serror( "relative too far" );
  135. emit2( opc );
  136. emit2( (int)adjust(exp.val) );
  137. }
  138. shiftcode( w1, w2 )
  139. int w1, w2;
  140. { switch( w1 & 0x0F04 )
  141. { /* Remember: w2 negative means right shift ! */
  142. case 0x200: /*byte*/ fit( w2>=-8 && w2<=8 ); break;
  143. case 0x300: /*word*/ fit( w2>=-16 && w2<=16 ); break;
  144. case 0x304: /*long*/ fit( w2>=-32 && w2<=32 ); break;
  145. }
  146. emit2( w1 );
  147. emit2( w2 );
  148. }
  149. argerr()
  150. { serror( "illegal operand" ); }