ass50.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. */
  6. #include "ass00.h"
  7. #include "assex.h"
  8. #include "ip_spec.h"
  9. #ifndef NORCSID
  10. static char rcs_id[] = "$Id$" ;
  11. #endif
  12. /*
  13. ** Pass 5 of EM1 assembler/loader
  14. ** Fix reloc tables
  15. ** Write out code
  16. */
  17. pass_5() {
  18. register line_t *lnp;
  19. cons_t off1;
  20. char defined ;
  21. int afterlength, partype ;
  22. register int inslength, ope;
  23. char *op_curr ;
  24. pass = 5;
  25. afterlength = 0;
  26. for (lnp = pstate.s_fline ; lnp ; lnp= lnp->l_next, line_num++ ) {
  27. ope = ctrunc(lnp->instr_num);
  28. if ( ope==sp_ilb1 ) continue ;
  29. if ( ope==sp_fpseu ) {
  30. line_num = lnp->ad.ad_ln.ln_first ;
  31. continue ;
  32. }
  33. off1 = parval(lnp,&defined);
  34. if ( (op_curr = lnp->opoff)==NO_OFF ) {
  35. fatal("opoff assertion failed") ;
  36. }
  37. inslength = oplength(*op_curr) ;
  38. afterlength += inslength ;
  39. /*
  40. * Change absolute offset to a relative for branches.
  41. */
  42. partype= em_flag[ope]&EM_PAR ;
  43. if ( partype==PAR_B && defined ) {
  44. off1 -= afterlength;
  45. }
  46. #ifdef JOHAN
  47. if ( jflag ) {
  48. extern char em_mnem[][4] ;
  49. printf("%s %ld\n",em_mnem[ope],off1) ;
  50. }
  51. #endif
  52. if ( !defined && partype==PAR_G ) { /* must be external */
  53. text_reloc((lnp->type1==GLOSYM ?
  54. lnp->ad.ad_gp:lnp->ad.ad_df.df_gp),
  55. (FOFFSET)(textbytes+afterlength-inslength) ,
  56. op_curr-opchoice);
  57. xputarb(inslength,off1,tfile);
  58. textoff += inslength ;
  59. } else {
  60. genop(op_curr,off1,partype) ;
  61. }
  62. } /* end forloop */
  63. line_num-- ;
  64. patchcase();
  65. textbytes += prog_size;
  66. if ( textbytes>maxadr ) fatal("Maximum code area size exceeded") ;
  67. } /* end pass_5 */
  68. genop(startc,value,i_flag) char *startc ; cons_t value ; int i_flag ; {
  69. char *currc ;
  70. register flag ;
  71. char opc ;
  72. /*
  73. * Real code generation.
  74. */
  75. currc= startc ;
  76. flag = ctrunc(*currc++);
  77. opc = *currc++;
  78. if ( (flag&OPTYPE)!=OPNO ) {
  79. if ( !opfit(flag,*currc,value,i_flag) ) {
  80. fatal("parameter value unsuitable for selected opcode") ;
  81. }
  82. if ( flag&OPWORD ) {
  83. if ( value%wordsize!=0 ) {
  84. error("parameter not word multiple");
  85. }
  86. value /= wordsize ;
  87. }
  88. if ( flag&OPNZ ) {
  89. if ( value<=0 ) error("negative parameter");
  90. value-- ;
  91. }
  92. }
  93. if ( flag&OPESC ) put8(ESC) ;
  94. switch ( flag&OPTYPE ) {
  95. case OPMINI :
  96. opc += value<0 ? -1-value : value ;
  97. break ;
  98. case OPSHORT :
  99. if ( value<0 ) {
  100. opc += -1-(value>>8) ;
  101. } else {
  102. opc += value>>8 ;
  103. }
  104. break ;
  105. case OP32 :
  106. case OP64 :
  107. put8(ESC_L) ;
  108. }
  109. #ifdef DUMP
  110. if ( c_flag ) {
  111. switch(flag&OPTYPE) {
  112. case OP32 :
  113. case OP64 :
  114. opcnt3[opc&0377]= 1 ;
  115. break ;
  116. default :
  117. if ( flag&OPESC ) opcnt2[opc&0377]= 1 ;
  118. else opcnt1[opc&0377]= 1 ;
  119. break ;
  120. }
  121. }
  122. #endif
  123. put8(opc) ;
  124. switch( flag&OPTYPE ) {
  125. case OPNO:
  126. case OPMINI:
  127. break ;
  128. case OPSHORT:
  129. case OP8:
  130. put8((char)value) ;
  131. break ;
  132. case OP16:
  133. case OP16U:
  134. put16(int_cast value) ;
  135. break ;
  136. case OP32:
  137. put32(value) ;
  138. break ;
  139. case OP64:
  140. put64(value) ;
  141. break ;
  142. }
  143. }
  144. patchcase() {
  145. register relc_t *r;
  146. register locl_t *k;
  147. if ( r= pstate.s_fdata ) {
  148. r= r->r_next ;
  149. } else {
  150. r= f_data ;
  151. }
  152. for( ; r ; r= r->r_next ) {
  153. if (r->r_typ == RELLOC) {
  154. r->r_typ = RELADR;
  155. k = r->r_val.rel_lp;
  156. if (k->l_defined==YES)
  157. r->r_val.rel_i = k->l_min + textbytes;
  158. else
  159. error("case label at line %d undefined",
  160. k->l_min);
  161. }
  162. }
  163. }