Browse Source

Add support in ARM assembler reader for ldr reg, =literal syntax

git-svn-id: trunk@25157 -
Jeppe Johansen 12 years ago
parent
commit
d89b9a4311
4 changed files with 105 additions and 0 deletions
  1. 1 0
      .gitattributes
  2. 77 0
      compiler/arm/raarmgas.pas
  3. 9 0
      compiler/raatt.pas
  4. 18 0
      tests/tbs/tb0597.pp

+ 1 - 0
.gitattributes

@@ -9974,6 +9974,7 @@ tests/tbs/tb0593.pp svneol=native#text/pascal
 tests/tbs/tb0594.pp svneol=native#text/plain
 tests/tbs/tb0594.pp svneol=native#text/plain
 tests/tbs/tb0595.pp svneol=native#text/plain
 tests/tbs/tb0595.pp svneol=native#text/plain
 tests/tbs/tb0596.pp svneol=native#text/pascal
 tests/tbs/tb0596.pp svneol=native#text/pascal
+tests/tbs/tb0597.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tbs0594.pp svneol=native#text/pascal
 tests/tbs/tbs0594.pp svneol=native#text/pascal
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0060.pp svneol=native#text/plain

+ 77 - 0
compiler/arm/raarmgas.pas

@@ -718,6 +718,68 @@ Unit raarmgas;
               end;
               end;
           end;
           end;
 
 
+
+        procedure BuildDirectRef;
+
+          function GetConstLabel(const symname: string; ofs: aint): TAsmLabel;
+            var
+              hp: tai;
+              newconst: tai_const;
+              lab: TAsmLabel;
+            begin
+              if symname<>'' then
+                newconst:=tai_const.Createname(symname,ofs)
+              else
+                newconst:=tai_const.Create_32bit(ofs);
+
+              hp:=tai(current_procinfo.aktlocaldata.First);
+              while assigned(hp) do
+                begin
+                  if hp.typ=ait_const then
+                    begin
+                      if (tai_const(hp).sym=newconst.sym) and
+                         (tai_const(hp).value=newconst.value) and
+                         assigned(hp.Previous) and
+                         (tai(hp.previous).typ=ait_label) then
+                        begin
+                          newconst.Free;
+                          result:=tai_label(hp.Previous).labsym;
+                          exit;
+                        end;
+                    end;
+
+                  hp:=tai(hp.Next);
+                end;
+
+              current_asmdata.getjumplabel(lab);
+              current_procinfo.aktlocaldata.concat(tai_align.create(4));
+              current_procinfo.aktlocaldata.concat(tai_label.create(lab));
+              current_procinfo.aktlocaldata.concat(newconst);
+              result:=lab;
+            end;
+
+          var
+            symtype: TAsmsymtype;
+            sym: string;
+            val: aint;
+          begin
+            case actasmtoken of
+              AS_INTNUM,
+              AS_ID:
+                begin
+                  BuildConstSymbolExpression(true,false,false,val,sym,symtype);
+
+                  if symtype=AT_NONE then
+                    sym:='';
+
+                  reference_reset(oper.opr.ref,4);
+                  oper.opr.ref.base:=NR_PC;
+                  oper.opr.ref.symbol:=GetConstLabel(sym,val);
+                end;
+            end;
+          end;
+
+
       var
       var
         tempreg : tregister;
         tempreg : tregister;
         ireg : tsuperregister;
         ireg : tsuperregister;
@@ -741,6 +803,21 @@ Unit raarmgas;
               BuildConstantOperand(oper);
               BuildConstantOperand(oper);
             end;
             end;
 
 
+          AS_EQUAL:
+            begin
+              case actopcode of
+                A_LDRBT,A_LDRB,A_LDR,A_LDRH,A_LDRSB,A_LDRSH,A_LDRT,
+                A_LDREX,A_LDREXB,A_LDREXD,A_LDREXH:
+                  begin
+                    consume(AS_EQUAL);
+                    oper.InitRef;
+                    BuildDirectRef;
+                  end;
+              else
+                Message(asmr_e_invalid_opcode_and_operand);
+              end;
+            end;
+
           (*
           (*
           AS_INTNUM,
           AS_INTNUM,
           AS_MINUS,
           AS_MINUS,

+ 9 - 0
compiler/raatt.pas

@@ -48,6 +48,7 @@ unit raatt;
         AS_RPAREN,AS_COLON,AS_DOT,AS_PLUS,AS_MINUS,AS_STAR,
         AS_RPAREN,AS_COLON,AS_DOT,AS_PLUS,AS_MINUS,AS_STAR,
         AS_SEPARATOR,AS_ID,AS_REGISTER,AS_OPCODE,AS_SLASH,AS_DOLLAR,
         AS_SEPARATOR,AS_ID,AS_REGISTER,AS_OPCODE,AS_SLASH,AS_DOLLAR,
         AS_HASH,AS_LSBRACKET,AS_RSBRACKET,AS_LBRACKET,AS_RBRACKET,
         AS_HASH,AS_LSBRACKET,AS_RSBRACKET,AS_LBRACKET,AS_RBRACKET,
+        AS_EQUAL,
         {------------------ Assembler directives --------------------}
         {------------------ Assembler directives --------------------}
         AS_DB,AS_DW,AS_DD,AS_DQ,AS_GLOBAL,
         AS_DB,AS_DW,AS_DD,AS_DQ,AS_GLOBAL,
         AS_ALIGN,AS_BALIGN,AS_P2ALIGN,AS_ASCII,
         AS_ALIGN,AS_BALIGN,AS_P2ALIGN,AS_ASCII,
@@ -75,6 +76,7 @@ unit raatt;
         ')',':','.','+','-','*',
         ')',':','.','+','-','*',
         ';','identifier','register','opcode','/','$',
         ';','identifier','register','opcode','/','$',
         '#','{','}','[',']',
         '#','{','}','[',']',
+        '=',
         '.byte','.word','.long','.quad','.globl',
         '.byte','.word','.long','.quad','.globl',
         '.align','.balign','.p2align','.ascii',
         '.align','.balign','.p2align','.ascii',
         '.asciz','.lcomm','.comm','.single','.double','.tfloat','.tcfloat',
         '.asciz','.lcomm','.comm','.single','.double','.tfloat','.tcfloat',
@@ -651,6 +653,13 @@ unit raatt;
                  c:=current_scanner.asmgetchar;
                  c:=current_scanner.asmgetchar;
                  exit;
                  exit;
                end;
                end;
+
+             '=' :
+               begin
+                 actasmtoken:=AS_EQUAL;
+                 c:=current_scanner.asmgetchar;
+                 exit;
+               end;
 {$endif arm}
 {$endif arm}
 
 
              ',' :
              ',' :

+ 18 - 0
tests/tbs/tb0597.pp

@@ -0,0 +1,18 @@
+{ %cpu=arm }
+program tb0597;
+
+var x: longword;
+
+procedure test; assembler; nostackframe;
+asm
+   ldr r0, =x
+   ldr r1, =0x12345678
+   str r1, [r0]
+end;
+
+begin
+   test;
+   
+   if x <> $12345678 then
+      halt(1);
+end.