home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / assembler / as / src / c / fix < prev    next >
Encoding:
Text File  |  1992-07-21  |  7.7 KB  |  245 lines

  1.  
  2. /*
  3.  * fix.c
  4.  * Copyright © 1992 Niklas Röjemo
  5.  */
  6.  
  7. #include "error.h"
  8. #include "help_cpu.h"
  9. #include "fix.h"
  10. #include "global.h"
  11. #include "m_cpu.h"
  12. #include "m_fpu.h"
  13. #include "option.h"
  14.  
  15. WORD fixShiftImm(int lineno, WORD shiftop, int shift)
  16. {
  17.   switch(shiftop) {
  18.     case LSL:
  19.       if(shift<0 || shift>31) {
  20.         errorLine(lineno,ErrorError,TRUE,"Illegal immediate shift %d.",shift);
  21.         shift = 1;
  22.       } break;
  23.     case LSR:
  24.       if(shift == 0) shiftop = LSL;
  25.       else if(shift<1 || shift>32) {
  26.         errorLine(lineno,ErrorError,TRUE,"Illegal immediate shift %d.",shift);
  27.         shift = 1;
  28.       } break;
  29.     case ASR:
  30.       if(shift == 0) shiftop = LSL;
  31.       else if(shift<1 || shift>32) {
  32.         errorLine(lineno,ErrorError,TRUE,"Illegal immediate shift %d.",shift);
  33.         shift = 1;
  34.       } break;
  35.     case ROR:
  36.       if(shift == 0) shiftop = LSL;
  37.       else if(shift<1 || shift>31) {
  38.         errorLine(lineno,ErrorError,TRUE,"Illegal immediate shift %d.",shift);
  39.         shift = 1;
  40.       } break;
  41.     default:
  42.       errorLine(lineno,ErrorSerious,FALSE,"Internal error in getshift.");
  43.   }
  44.   return SHIFT_IMM(shift) | SHIFT_OP(shiftop);
  45. }
  46.  
  47. extern int pedantic;
  48.  
  49. WORD fixImm8s4(int lineno, WORD ir, int im)
  50. {
  51.   int i8s4 = help_cpuImm8s4(im);
  52.   if(i8s4 == -1) { /* Not a legal immediate */
  53.     switch(ir & M_MNEM) { /* try changing opcode */
  54.     case M_ADD:
  55.       if((i8s4 = help_cpuImm8s4(-im)) != -1) {
  56.         ir = (ir & ~M_MNEM) | M_SUB;
  57.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing add r_,r_,#%d to sub r_,r_,#%d.",im,-im);
  58.       } break;
  59.     case M_SUB:
  60.       if((i8s4 = help_cpuImm8s4(-im)) != -1) {
  61.         ir = (ir & ~M_MNEM) | M_ADD;
  62.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing sub r_,r_,#%d to add r_,r_,#%d.",im,-im);
  63.       } break;
  64.     case M_ADC:
  65.       if((i8s4 = help_cpuImm8s4(-im)) != -1) {
  66.         ir = (ir & ~M_MNEM) | M_SBC;
  67.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing adc r_,r_,#%d to sbc r_,r_,#%d.",im,-im);
  68.       } break;
  69.     case M_SBC:
  70.       if((i8s4 = help_cpuImm8s4(-im)) != -1) {
  71.         ir = (ir & ~M_MNEM) | M_ADC;
  72.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing sbc r_,r_,#%d to adc r_,r_,#%d.",im,-im);
  73.       } break;
  74.     case M_CMP:
  75.       if((i8s4 = help_cpuImm8s4(-im)) != -1) {
  76.         ir = (ir & ~M_MNEM) | M_CMN;
  77.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing cmp r_,#%d to cmn r_,r_,#%d.",im,-im);
  78.       } break;
  79.     case M_CMN:
  80.       if((i8s4 = help_cpuImm8s4(-im)) != -1) {
  81.         ir = (ir & ~M_MNEM) | M_CMP;
  82.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing cmn r_,#%d to cmp r_,#%d.",im,-im);
  83.       } break;
  84.     case M_MOV:
  85.       if((i8s4 = help_cpuImm8s4(~im)) != -1) {
  86.         ir = (ir & ~M_MNEM) | M_MVN;
  87.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing mov r_,#%d to mvn r_,#%d.",im,~im);
  88.       } break;
  89.     case M_MVN:
  90.       if((i8s4 = help_cpuImm8s4(~im)) != -1) {
  91.         ir = (ir & ~M_MNEM) | M_MOV;
  92.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing mvn r_,#%d to mov r_,#%d.",im,~im);
  93.       } break;
  94.     case M_AND:
  95.       if((i8s4 = help_cpuImm8s4(~im)) != -1) {
  96.         ir = (ir & ~M_MNEM) | M_BIC;
  97.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing and r_,r_,#0x%x to bic r_,r_,#0x%x.",im,~im);
  98.       } break;
  99.     case M_BIC:
  100.       if((i8s4 = help_cpuImm8s4(~im)) != -1) {
  101.         ir = (ir & ~M_MNEM) | M_AND;
  102.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing bic r_,r_,#0x%x to and r_,r_,#0x%x.",im,~im);
  103.       } break;
  104.     }
  105.   }
  106.   if(i8s4 == -1) {
  107.     errorLine(lineno,ErrorError,TRUE,"Illegal immediate constant %d (0x%08x).",im,im);
  108.     i8s4 = 0;
  109.   }
  110.   return ir|i8s4; 
  111. }
  112.  
  113. WORD fixImmFloat(int lineno, WORD ir, FLOAT im)
  114. {
  115.   int f = fpuImm(im);
  116.   if(f == -1) { /* Not a legal float immediate */
  117.     switch(ir & M_FMNEM) { /* try changing opcode */
  118.     case M_ADF:
  119.       if((f = fpuImm(-im)) != -1) {
  120.         ir = (ir & ~M_FMNEM) | M_SUF;
  121.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing adf f_,f_,#%.1f to suf f_,f_,#%.1f.",im,-im);
  122.       } break;
  123.     case M_SUF:
  124.       if((f = fpuImm(-im)) != -1) {
  125.         ir = (ir & ~M_FMNEM) | M_ADF;
  126.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing suf f_,f_,#%.1f to adf f_,f_,#%.1f.",im,-im);
  127.       } break;
  128.     case M_MVF:
  129.       if((f = fpuImm(-im)) != -1) {
  130.         ir = (ir & ~M_FMNEM) | M_MNF;
  131.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing mvf f_,#%.1f to mnf f_,#%.1f.",im,-im);
  132.       } break;
  133.     case M_MNF:
  134.       if((f = fpuImm(-im)) != -1) {
  135.         ir = (ir & ~M_FMNEM) | M_MVF;
  136.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing mnf f_,#%.1f to mvf f_,#%.1f.",im,-im);
  137.       } break;
  138.     case M_CMF&M_FMNEM:
  139.       if((f = fpuImm(-im)) != -1) {
  140.         ir = (ir & ~M_FMNEM) | M_CNF;
  141.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing cmf f_,#%.1f to cnf f_,#%.1f.",im,-im);
  142.       } break;
  143.     case M_CNF&M_FMNEM:
  144.       if((f = fpuImm(-im)) != -1) {
  145.         ir = (ir & ~M_FMNEM) | M_CMF;
  146.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing cnf f_,#%.1f to cmf f_,#%.1f.",im,-im);
  147.       } break;
  148.     case (M_CMF|EXEPTION_BIT)&M_FMNEM:
  149.       if((f = fpuImm(-im)) != -1) {
  150.         ir = (ir & ~M_FMNEM) | M_CNF|EXEPTION_BIT;
  151.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing cmfe f_,#%.1f to cnfe f_,#%.1f.",im,-im);
  152.       } break;
  153.     case (M_CNF|EXEPTION_BIT)&M_FMNEM:
  154.       if((f = fpuImm(-im)) != -1) {
  155.         ir = (ir & ~M_FMNEM) | M_CMF|EXEPTION_BIT;
  156.         if(pedantic) errorLine(lineno,ErrorInfo,TRUE,"Changing cnfe f_,#%.1f to cmfe f_,#%.1f.",im,-im);
  157.       } break;
  158.     }
  159.   }
  160.   if(f == -1) {
  161.     errorLine(lineno,ErrorError,TRUE,"Illegal immediate constant %g.",im);
  162.     f = 0;
  163.   }
  164.   return ir|f; 
  165. }
  166.  
  167. WORD fixAdr(int lineno, WORD ir, int im) /* !!! mov and mvn should be possible */
  168. {
  169.   int i8s4;
  170.   if(im<0) {
  171.     ir |= 0x00400000; /* sub */
  172.     im = -im;
  173.   } else
  174.     ir |= 0x00800000; /* add */
  175.   i8s4 = help_cpuImm8s4(im); 
  176.   if(i8s4 == -1)
  177.     errorLine(lineno,ErrorError,TRUE,"Offset %d (0x%08x) is illegal for adr.",im,im);
  178.   else
  179.    ir |= i8s4;
  180.   return ir;
  181. }
  182.  
  183. WORD fixSwi(int lineno, int im)
  184. {
  185.   if((im & 0xffffff) != im)
  186.     errorLine(lineno,ErrorError,TRUE,"Illegal swi number %d(0x%08x).",im,im);
  187.   return im&0xffffff;
  188. }
  189.  
  190. WORD fixBranch(int lineno, int im)
  191. {
  192.   if(im & 3)
  193.     errorLine(lineno,ErrorError,TRUE,"Branch value is not a multiple of four.");
  194.   return (im>>2)&0xffffff;
  195. }
  196.  
  197. WORD fixCopOffset(int lineno, WORD ir, int offset)
  198. {
  199.   BOOL up = TRUE;
  200.   if(offset<0) { offset = -offset; up = FALSE; }
  201.   if(offset&3) errorLine(lineno,ErrorError,TRUE,"Offset %d is not a word offset.",offset);
  202.   if(offset>1020) errorLine(lineno,ErrorError,TRUE,"Offset %d is to large.",offset);
  203.   ir |= (offset>>2)&0xff;
  204.   if(up) ir |= UP_FLAG;  
  205.   return ir;
  206. }
  207.  
  208. WORD fixCpuOffset(int lineno, WORD ir, int offset)
  209. {
  210.   BOOL up = TRUE;
  211.   if(offset<0) { offset = -offset; up = FALSE; }
  212.   if(offset>4095) errorLine(lineno,ErrorError,TRUE,"Offset %d is to large.",offset);
  213.   ir |= offset&0xfff;
  214.   if(up) ir |= UP_FLAG;  
  215.   return ir;
  216. }
  217.  
  218. WORD fixMask(int lineno, int mask)
  219. {
  220.  if(mask < 0 || mask >0xffff)
  221.    errorLine(lineno,ErrorError,TRUE,"Illegal value for register mask 0x%x.",mask);
  222.  return mask&0xffff;
  223. }
  224.  
  225. WORD fixInt(int lineno, int size, int value)
  226. {
  227.   switch(size) {
  228.     case 1:
  229.       if(value<-128 || value>256) {
  230.         errorLine(lineno,ErrorError,TRUE,"Expression %d to big for 8 bits.",value);
  231.         value &= 0xff;
  232.       } break;
  233.     case 2:
  234.       if(value<-32768 || value>65536) {
  235.         errorLine(lineno,ErrorError,TRUE,"Expression %d to big for 16 bits.",value);
  236.         value &= 0xffff;
  237.       } break;
  238.     case 4:
  239.       break;
  240.     default:
  241.       errorLine(lineno,ErrorSerious,TRUE,"Internal fixInt: Size %d is not legal.",size);
  242.   }
  243.   return value;
  244. }
  245.