home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / assembler / as / src / c / m_cpumem < prev    next >
Encoding:
Text File  |  1993-03-07  |  6.4 KB  |  232 lines

  1.  
  2. /*
  3.  * m_cpumem.c
  4.  * Copyright © 1992 Niklas Röjemo
  5.  */
  6.  
  7. #include "mnemonics.h"
  8. #include "error.h"
  9. #include "option.h"
  10. #include "put.h"
  11. #include "input.h"
  12. #include "global.h"
  13. #include "expr.h"
  14. #include "code.h"
  15. #include "area.h"
  16. #include "lit.h"
  17. #include "get.h"
  18. #include "fix.h"
  19. #include "expr.h"
  20.  
  21.  
  22. static void dstmem(unsigned int ir)
  23. {
  24.   int op;
  25.   BOOL trans = FALSE;
  26.   BOOL pre;
  27.   Value offset;
  28.   op = getCpuReg();
  29.   ir |= DST_OP(op);
  30.   skipblanks();
  31.   if(inputLook() == ',') { inputSkip(); skipblanks(); }
  32.   else error(ErrorError,TRUE,"Inserting missing comma before address.");
  33.   switch(inputLook()) {
  34.     case '[':   /* ldr reg,[ */
  35.     { BOOL up = TRUE;
  36.       inputSkip();
  37.       skipblanks();
  38.       op = getCpuReg();       /* Base register */
  39.       ir |= LHS_OP(op);
  40.       skipblanks();
  41.       if(inputLook() == ']') { pre = FALSE; inputSkip(); skipblanks(); }
  42.       else pre = TRUE;
  43.       if(inputLook() == ',') { /* either [base,XX] or [base],XX */
  44.         inputSkip();
  45.         skipblanks();
  46.         if(inputLook() == '+') { inputSkip(); skipblanks(); }
  47.         else if(inputLook() == '-') { inputSkip(); skipblanks(); up = FALSE;}
  48.         if(inputLook() == '#') {
  49.           inputSkip();
  50.           exprBuild();
  51.           if(!up) codeOperator(Op_neg);
  52.           offset = exprEval(ValueInt |ValueCode|ValueLateLabel);
  53.           switch(offset.Tag) {
  54.           case ValueInt:
  55.             ir = fixCpuOffset(inputLineNo,ir,offset.ValueInt.i);
  56.             break;
  57.           case ValueCode: case ValueLateLabel:
  58.             relocCpuOffset(ir,offset);
  59.             break;
  60.           default:
  61.             error(ErrorError,TRUE,"Illegal offset expression.");
  62.             break;
  63.           }
  64.           /* UP_FLAG is fixed in fixCpuOffset */
  65.         } else {
  66.           ir |= REG_FLAG;
  67.           ir = getRhs(TRUE,ir); /* Can only be Reg {,shiftop {#shift}} */
  68.           if(up)
  69.             ir |= UP_FLAG;     /* !! Fixed !! */
  70.         }
  71.         skipblanks();
  72.       } else { /* [base] if this way */
  73.         ir |= UP_FLAG;     /* 0 nicer than -0 */
  74.         if(pre)
  75.           error(ErrorError,TRUE,"Illegal character '%c' after base.",inputLook());
  76.       } 
  77.       if(pre) {
  78.         if(inputLook() == ']') { inputSkip(); skipblanks(); }
  79.         else error(ErrorError,TRUE,"Inserting missing ] after address.");
  80.       }
  81.       if(inputLook() == '!') { 
  82.         if(pre) ir |= WB_FLAG;
  83.         else error(ErrorError,TRUE,"Writeback not allowed together with post-(inc/dec)rement.");
  84.         inputSkip();
  85.         skipblanks();
  86.       }
  87.       if(pre) {
  88.         ir |= PRE_FLAG;
  89.         if(trans)
  90.           error(ErrorError,TRUE,"Translate not allowed together with pre-(inc/dec)rement.");
  91.       }
  92.     } break;
  93.   case '=':
  94.     if(ir & 0x00100000) { /* only allowed for ldr */
  95.       ir |= PRE_FLAG | LHS_OP(15);
  96.       inputSkip();
  97.       exprBuild();
  98.       litInt(4,exprEval(ValueInt | ValueString|ValueCode|ValueLateLabel));
  99.     } else {
  100.       error(ErrorError,FALSE,"You can't store into a constant!.");
  101.     } break;
  102.   default:  /* ldr reg,label */
  103.     ir |= PRE_FLAG | LHS_OP(15);
  104.     exprBuild();
  105.     codePosition(areaCurrent);
  106.     codeOperator(Op_sub);
  107.     codeInt(8);
  108.     codeOperator(Op_sub);
  109.     offset = exprEval(ValueInt |ValueCode|ValueLateLabel);
  110.     switch(offset.Tag) {
  111.     case ValueInt:
  112.       ir = fixCpuOffset(inputLineNo,ir,offset.ValueInt.i);
  113.       break;
  114.     case ValueCode: case ValueLateLabel:
  115.       relocCpuOffset(ir,offset);
  116.       break;
  117.     default:
  118.       error(ErrorError,TRUE,"Illegal address expression.");
  119.       break;
  120.     }
  121.   }
  122.   putIns(ir);
  123. }
  124.  
  125. void m_ldr(unsigned int cc)
  126. {
  127.   dstmem(cc|0x04100000);
  128. }
  129.  
  130. void m_str(unsigned int cc)
  131. {
  132.   dstmem(cc|0x04000000);
  133. }
  134.  
  135. static void dstreglist(unsigned int ir)
  136. {
  137.   int op,low,high,c;
  138.   Value mask;
  139.   op = getCpuReg();
  140.   ir |= BASE_MULTI(op);
  141.   skipblanks();
  142.   if(inputLook() == '!') { inputSkip(); ir |= WB_FLAG; skipblanks();}
  143.   if(inputLook() == ',') { inputSkip(); skipblanks();}
  144.   else error(ErrorError,TRUE,"Inserting missing comma before reglist.");
  145.   if(inputLook() == '#') {  /* constant */
  146.     exprBuild();
  147.     mask = exprEval(ValueInt | ValueCode|ValueLateLabel);
  148.     switch(mask.Tag) {
  149.     case ValueInt:
  150.       ir |= fixMask(inputLineNo,mask.ValueInt.i);
  151.       break;
  152.     case ValueCode: case ValueLateLabel:
  153.       relocMask(mask);
  154.       break;
  155.     default:
  156.       error(ErrorError,TRUE,"Illegal mask expression.");
  157.       break;
  158.     }
  159.   } else {
  160.     if(inputLook() == '{') { inputSkip(); }
  161.     else error(ErrorError,TRUE,"Inserting missing '{' before reglist.");
  162.     op = 0;
  163.     do {
  164.       skipblanks();
  165.       low = getCpuReg();
  166.       skipblanks();
  167.       switch(c=inputLook()) {
  168.         case '-':
  169.           inputSkip(); 
  170.           skipblanks();
  171.           high = getCpuReg();
  172.           skipblanks();
  173.           if(low>high) {
  174.             error(ErrorInfo,TRUE,"Register interval in wrong order r%d-r%d.",low,high);
  175.             c = low; low = high; high = c;
  176.           }
  177.           break;
  178.         case ',':  case '}':
  179.           high = low;
  180.           break;
  181.         default: error(ErrorError,TRUE,"Illegal character '%c' in register list.",c);
  182.       }
  183.       if(1<<low < op)
  184.         error(ErrorInfo,TRUE,"Registers in wrong order.");
  185.       if( ((1<<(high+1))-(1<<low)) & op)
  186.         error(ErrorInfo,TRUE,"Register occures more than once in register list.");
  187.       op |= (1<<(high+1))-(1<<low);
  188.     } while((c=inputGet()) == ',');
  189.     if(c != '}') { inputUnGet(c); error(ErrorError,TRUE,"Inserting missing '}' after reglist."); }
  190.     ir |= op;
  191.   }
  192.   skipblanks();
  193.   if(inputLook() == '^') {
  194.     inputSkip();
  195.     if(ir & WB_FLAG && !(ir & (1<<15)))
  196.       error(ErrorInfo,TRUE,"Writeback together with force user.");
  197.     ir |= FORCE_FLAG;
  198.     skipblanks();
  199.   }
  200.   putIns(ir);
  201. }
  202.  
  203. void m_ldm(unsigned int cc)
  204. {
  205.   dstreglist(cc|0x08100000);
  206. }
  207.  
  208. void m_stm(unsigned int cc)
  209. {
  210.   dstreglist(cc|0x08000000);
  211. }
  212.  
  213. void m_swp(unsigned int cc)
  214. {
  215.   int ir = cc | 0x01000090;
  216.   ir |= DST_OP(getCpuReg());
  217.   skipblanks();
  218.   if(inputLook() == ',') {inputSkip(); skipblanks();}
  219.   else error(ErrorError,TRUE,"Inserting a comma after dst.");
  220.   ir |= RHS_OP(getCpuReg());  /* Note wrong order swp dst,rhs,[lsh] */
  221.   skipblanks();
  222.   if(inputLook() == ',') {inputSkip(); skipblanks();}
  223.   else error(ErrorError,TRUE,"Inserting a comma after lhs.");
  224.   if(inputLook() == '[') {inputSkip(); skipblanks();}
  225.   else error(ErrorError,TRUE,"Inserting missing '['.");
  226.   ir |= LHS_MUL(getCpuReg());
  227.   skipblanks();
  228.   if(inputLook() == ']') {inputSkip(); skipblanks();}
  229.   else error(ErrorError,TRUE,"Inserting missing ']'.");
  230.   putIns(ir);
  231. }
  232.