Browse Source

* sparc assembler reader updates

peter 21 năm trước cách đây
mục cha
commit
e380119e8c
2 tập tin đã thay đổi với 132 bổ sung185 xóa
  1. 21 4
      compiler/raatt.pas
  2. 111 181
      compiler/sparc/racpugas.pas

+ 21 - 4
compiler/raatt.pas

@@ -55,7 +55,8 @@ unit raatt;
         AS_ASCIIZ,AS_LCOMM,AS_COMM,AS_SINGLE,AS_DOUBLE,AS_EXTENDED,
         AS_DATA,AS_TEXT,AS_END,
         {------------------ Assembler Operators  --------------------}
-        AS_TYPE,AS_MOD,AS_SHL,AS_SHR,AS_NOT,AS_AND,AS_OR,AS_XOR,AS_NOR,AS_AT);
+        AS_TYPE,AS_MOD,AS_SHL,AS_SHR,AS_NOT,AS_AND,AS_OR,AS_XOR,AS_NOR,AS_AT,
+        AS_LO,AS_HI);
 
         tasmkeyword = string[10];
 
@@ -75,7 +76,7 @@ unit raatt;
         '.align','.balign','.p2align','.ascii',
         '.asciz','.lcomm','.comm','.single','.double','.tfloat',
         '.data','.text','END',
-        'TYPE','%','<<','>>','!','&','|','^','~','@');
+        'TYPE','%','<<','>>','!','&','|','^','~','@','lo','hi');
 
     type
        tattreader = class(tasmreader)
@@ -1202,6 +1203,17 @@ unit raatt;
                 expr:=expr + '(';
                 inc(parenlevel);
               end;
+            AS_RBRACKET:
+              begin
+                if betweenbracket then
+                  break;
+                { write error only once. }
+                if not errorflag then
+                  Message(asmr_e_invalid_constant_expression);
+                { consume tokens until we find COMMA or SEPARATOR }
+                Consume(actasmtoken);
+                errorflag:=TRUE;
+              end;
             AS_RPAREN:
               Begin
                 { end of ref ? }
@@ -1417,7 +1429,9 @@ unit raatt;
                     end;
                  end;
                 { check if there are wrong operator used like / or mod etc. }
-                if (hs<>'') and not(actasmtoken in [AS_MINUS,AS_PLUS,AS_COMMA,AS_SEPARATOR,AS_LPAREN,AS_END]) then
+                if (hs<>'') and
+                   not(actasmtoken in [AS_MINUS,AS_PLUS,AS_COMMA,AS_SEPARATOR,
+                                       AS_LPAREN,AS_RPAREN,AS_RBRACKET,AS_END]) then
                  Message(asmr_e_only_add_relocatable_symbol);
               end;
             AS_END,
@@ -1478,7 +1492,10 @@ end.
 
 {
   $Log$
-  Revision 1.7  2003-12-08 17:43:57  florian
+  Revision 1.8  2003-12-25 01:25:43  peter
+    * sparc assembler reader updates
+
+  Revision 1.7  2003/12/08 17:43:57  florian
     * fixed ldm/stm arm assembler reading
     * fixed a_load_reg_reg with OS_8 on ARM
     * non supported calling conventions cause only a warning now

+ 111 - 181
compiler/sparc/racpugas.pas

@@ -119,126 +119,74 @@ Interface
 
 
     Procedure tSparcReader.BuildReference(oper : tSparcoperand);
-
-      procedure Consume_RParen;
-        begin
-          if actasmtoken <> AS_RPAREN then
-           Begin
-             Message(asmr_e_invalid_reference_syntax);
-             RecoverConsume(true);
-           end
-          else
-           begin
-             Consume(AS_RPAREN);
-             if not (actasmtoken in [AS_COMMA,AS_SEPARATOR,AS_END]) then
+      var
+        l : longint;
+        regs : byte;
+        hasimm : boolean;
+      begin
+        regs:=0;
+        hasimm:=false;
+        Consume(AS_LBRACKET);
+        repeat
+          Case actasmtoken of
+            AS_INTNUM,
+            AS_MINUS,
+            AS_PLUS:
               Begin
-                Message(asmr_e_invalid_reference_syntax);
-                RecoverConsume(true);
+                if hasimm or (regs>1) then
+                 Begin
+                   Message(asmr_e_invalid_reference_syntax);
+                   RecoverConsume(true);
+                   break;
+                 End;
+                oper.opr.Ref.Offset:=BuildConstExpression(false,true);
+                hasimm:=true;
+              End;
+
+            AS_REGISTER:
+              Begin
+                if regs<2 then
+                  begin
+                    if regs=0 then
+                      oper.opr.ref.base:=actasmregister
+                    else
+                      oper.opr.ref.index:=actasmregister;
+                    inc(regs);
+                  end
+                else
+                  begin
+                    Message(asmr_e_invalid_reference_syntax);
+                    RecoverConsume(true);
+                    break;
+                  end;
+                Consume(AS_REGISTER);
               end;
-           end;
-        end;
 
-      var
-        l : longint;
+            AS_ID:
+              Begin
+                l:=BuildConstExpression(true,true);
+                inc(oper.opr.ref.offset,l);
+              End;
 
-      begin
-        Consume(AS_LPAREN);
-        Case actasmtoken of
-          AS_INTNUM,
-          AS_MINUS,
-          AS_PLUS:
-            Begin
-              { offset(offset) is invalid }
-              If oper.opr.Ref.Offset <> 0 Then
-               Begin
-                 Message(asmr_e_invalid_reference_syntax);
-                 RecoverConsume(true);
-               End
-              Else
-               Begin
-                 oper.opr.Ref.Offset:=BuildConstExpression(false,true);
-                 Consume(AS_RPAREN);
-                 if actasmtoken=AS_MOD then
-                   ReadPercent(oper);
-               end;
-              exit;
-            End;
-          AS_REGISTER: { (reg ...  }
-            Begin
-              if ((oper.opr.typ=OPR_REFERENCE) and (oper.opr.ref.base<>NR_NO)) or
-                 ((oper.opr.typ=OPR_LOCAL) and (oper.opr.localsym.localloc.loc<>LOC_REGISTER)) then
-                message(asmr_e_cannot_index_relative_var);
-              oper.opr.ref.base:=actasmregister;
-              Consume(AS_REGISTER);
-              { can either be a register or a right parenthesis }
-              { (reg)        }
-              if actasmtoken=AS_RPAREN then
-               Begin
-                 Consume_RParen;
-                 exit;
-               end;
-              { (reg,reg ..  }
-              Consume(AS_COMMA);
-              if (actasmtoken=AS_REGISTER) and
-                 (oper.opr.Ref.Offset = 0) then
-               Begin
-                 oper.opr.ref.index:=actasmregister;
-                 Consume(AS_REGISTER);
-                 Consume_RParen;
-               end
-              else
-               Begin
-                 Message(asmr_e_invalid_reference_syntax);
-                 RecoverConsume(false);
-               end;
-            end; {end case }
-          AS_ID:
-            Begin
-              ReadSym(oper);
-              { add a constant expression? }
-              if (actasmtoken=AS_PLUS) then
-               begin
-                 l:=BuildConstExpression(true,true);
-                 case oper.opr.typ of
-                   OPR_CONSTANT :
-                     inc(oper.opr.val,l);
-                   OPR_LOCAL :
-                     inc(oper.opr.localsymofs,l);
-                   OPR_REFERENCE :
-                     inc(oper.opr.ref.offset,l);
-                   else
-                     internalerror(200309202);
-                 end;
-               end;
-              Consume(AS_RPAREN);
-              if actasmtoken=AS_MOD then
-                ReadPercent(oper);
-            End;
-          AS_COMMA: { (, ...  can either be scaling, or index }
-            Begin
-              Consume(AS_COMMA);
-              { Index }
-              if (actasmtoken=AS_REGISTER) then
-                Begin
-                  oper.opr.ref.index:=actasmregister;
-                  Consume(AS_REGISTER);
-                  { check for scaling ... }
-                  Consume_RParen;
-                end
-              else
-                begin
+            AS_RBRACKET:
+              begin
+                if (regs=0) and (not hasimm) then
                   Message(asmr_e_invalid_reference_syntax);
-                  RecoverConsume(false);
-                end;
-            end;
-        else
-          Begin
-            Message(asmr_e_invalid_reference_syntax);
-            RecoverConsume(false);
+                Consume(AS_RBRACKET);
+                break;
+              end;
+
+            else
+              Begin
+                Message(asmr_e_invalid_reference_syntax);
+                RecoverConsume(false);
+                break;
+              end;
           end;
-        end;
+        until false;
       end;
 
+
     procedure TSparcReader.handlepercent;
       var
         len : longint;
@@ -257,18 +205,20 @@ Interface
          uppervar(actasmpattern);
          if is_register(actasmpattern) then
            exit;
-         if(actasmpattern='%HI')or(actasmpattern='%LO')then
-           actasmtoken:=AS_MOD
+         if (actasmpattern='%HI') then
+           actasmtoken:=AS_HI
+         else if (actasmpattern='%LO')then
+           actasmtoken:=AS_LO
          else
            Message(asmr_e_invalid_register);
       end;
 
+
     Procedure tSparcReader.BuildOperand(oper : tSparcoperand);
       var
         expr : string;
         typesize,l : longint;
 
-
         procedure AddLabelOperand(hl:tasmlabel);
           begin
             if not(actasmtoken in [AS_PLUS,AS_MINUS,AS_LPAREN]) and
@@ -328,60 +278,13 @@ Interface
             end;
           end;
 
-
-        function MaybeBuildReference:boolean;
-          { Try to create a reference, if not a reference is found then false
-            is returned }
-          begin
-            MaybeBuildReference:=true;
-            case actasmtoken of
-              AS_INTNUM,
-              AS_MINUS,
-              AS_PLUS:
-                Begin
-                  oper.opr.ref.offset:=BuildConstExpression(True,False);
-                  if actasmtoken<>AS_LPAREN then
-                    Message(asmr_e_invalid_reference_syntax)
-                  else
-                    BuildReference(oper);
-                end;
-              AS_LPAREN:
-                BuildReference(oper);
-              AS_ID: { only a variable is allowed ... }
-                Begin
-                  ReadSym(oper);
-                  case actasmtoken of
-                    AS_END,
-                    AS_SEPARATOR,
-                    AS_COMMA: ;
-                    AS_LPAREN:
-                      BuildReference(oper);
-                  else
-                    Begin
-                      Message(asmr_e_invalid_reference_syntax);
-                      Consume(actasmtoken);
-                    end;
-                  end; {end case }
-                end;
-              else
-               MaybeBuildReference:=false;
-            end; { end case }
-          end;
-
-
       var
         tempreg : tregister;
+        tempstr : string;
         hl : tasmlabel;
-        ofs : longint;
       Begin
         expr:='';
         case actasmtoken of
-          AS_LPAREN: { Memory reference or constant expression }
-            Begin
-              oper.InitRef;
-              BuildReference(oper);
-            end;
-
           AS_INTNUM,
           AS_MINUS,
           AS_PLUS,
@@ -391,14 +294,42 @@ Interface
               { This must absolutely be followed by (  }
               oper.InitRef;
               oper.opr.ref.offset:=BuildConstExpression(True,False);
-              if actasmtoken<>AS_LPAREN then
-                begin
-                  ofs:=oper.opr.ref.offset;
-                  BuildConstantOperand(oper);
-                  inc(oper.opr.val,ofs);
-                end
+            end;
+
+          AS_LBRACKET :
+            begin
+              { memory reference }
+              BuildReference(oper);
+            end;
+
+          AS_HI,
+          AS_LO:
+            begin
+              { Low or High part of a constant (or constant
+                memory location) }
+              oper.InitRef;
+              if actasmtoken=AS_LO then
+                oper.opr.ref.symaddr:=refs_lo
+              else
+                oper.opr.ref.symaddr:=refs_hi;
+              Consume(actasmtoken);
+              Consume(AS_LPAREN);
+              BuildConstSymbolExpression(false, true,false,l,tempstr);
+              if not assigned(oper.opr.ref.symbol) then
+                oper.opr.ref.symbol:=objectlibrary.newasmsymbol(tempstr)
               else
-                BuildReference(oper);
+                Message(asmr_e_cant_have_multiple_relocatable_symbols);
+              case oper.opr.typ of
+                OPR_CONSTANT :
+                  inc(oper.opr.val,l);
+                OPR_LOCAL :
+                  inc(oper.opr.localsymofs,l);
+                OPR_REFERENCE :
+                  inc(oper.opr.ref.offset,l);
+                else
+                  internalerror(200309202);
+              end;
+              Consume(AS_RPAREN);
             end;
 
           AS_ID: { A constant expression, or a Variable ref.  }
@@ -503,9 +434,6 @@ Interface
                      end;
                    end
                end;
-              { Do we have a indexing reference, then parse it also }
-              if actasmtoken=AS_LPAREN then
-                BuildReference(oper);
             end;
 
           AS_REGISTER: { Register, a variable reference or a constant reference  }
@@ -520,7 +448,7 @@ Interface
                     oper.opr.typ:=OPR_REGISTER;
                     oper.opr.reg:=tempreg;
                   end
-              else 
+              else
                 Message(asmr_e_syn_operand);
             end;
           AS_END,
@@ -625,12 +553,11 @@ Interface
     because we take the whole remaining string without the leading B }
             actopcode := A_Bxx;
             for cond:=low(TAsmCond) to high(TAsmCond) do
-              if(cond in [C_AE])and(Upper(copy(s,2,length(s)-1))=Upper(Cond2Str[cond])) then
-              begin
-              WriteLn('Bxx');
-                actasmtoken:=AS_OPCODE;
-                is_asmopcode:=true;
-              end;
+              if (Upper(copy(s,2,length(s)-1))=Upper(Cond2Str[cond])) then
+                begin
+                  actasmtoken:=AS_OPCODE;
+                  is_asmopcode:=true;
+                end;
           end;
       end;
     procedure tSparcReader.ConvertCalljmp(instr : tSparcinstruction);
@@ -694,7 +621,10 @@ initialization
 end.
 {
   $Log$
-  Revision 1.2  2003-12-10 13:16:36  mazen
+  Revision 1.3  2003-12-25 01:25:43  peter
+    * sparc assembler reader updates
+
+  Revision 1.2  2003/12/10 13:16:36  mazen
   * improve hadlign %hi and %lo operators
 
   Revision 1.1  2003/12/08 13:02:21  mazen