mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 00:39:35 +01:00 
			
		
		
		
	+ typecasting support for variables, but be carefull as word,byte can't
be used because they are reserved assembler keywords
This commit is contained in:
		
							parent
							
								
									2f715a886a
								
							
						
					
					
						commit
						8900400a2c
					
				@ -345,7 +345,7 @@ begin
 | 
			
		||||
              {               - field of object/record                         }
 | 
			
		||||
              {               - directive.                                     }
 | 
			
		||||
         begin
 | 
			
		||||
           if (prevasmtoken=AS_ID) then
 | 
			
		||||
           if (prevasmtoken in [AS_ID,AS_RPAREN]) then
 | 
			
		||||
            begin
 | 
			
		||||
              c:=current_scanner^.asmgetchar;
 | 
			
		||||
              actasmtoken:=AS_DOT;
 | 
			
		||||
@ -1201,7 +1201,9 @@ end;
 | 
			
		||||
 | 
			
		||||
Procedure T386ATTOperand.BuildOperand;
 | 
			
		||||
var
 | 
			
		||||
  tempstr,tempstr2,
 | 
			
		||||
  expr : string;
 | 
			
		||||
  l,k : longint;
 | 
			
		||||
 | 
			
		||||
  procedure AddLabelOperand(hl:pasmlabel);
 | 
			
		||||
  begin
 | 
			
		||||
@ -1242,7 +1244,7 @@ var
 | 
			
		||||
     inc(l,BuildConstExpression(true,false));
 | 
			
		||||
    if opr.typ=OPR_REFERENCE then
 | 
			
		||||
     begin
 | 
			
		||||
       if hasdot and (opr.ref.options=ref_parafixup) then
 | 
			
		||||
       if hasdot and (not hastype) and (opr.ref.options=ref_parafixup) then
 | 
			
		||||
        Message(asmr_e_cannot_access_field_directly_for_parameters);
 | 
			
		||||
       inc(opr.ref.offset,l)
 | 
			
		||||
     end
 | 
			
		||||
@ -1270,9 +1272,29 @@ var
 | 
			
		||||
        BuildReference;
 | 
			
		||||
      AS_ID: { only a variable is allowed ... }
 | 
			
		||||
        Begin
 | 
			
		||||
          if not SetupVar(actasmpattern,false) then
 | 
			
		||||
            Message(asmr_e_invalid_reference_syntax);
 | 
			
		||||
          tempstr:=actasmpattern;
 | 
			
		||||
          Consume(AS_ID);
 | 
			
		||||
          { typecasting? }
 | 
			
		||||
          if (actasmtoken=AS_LPAREN) and
 | 
			
		||||
             SearchType(tempstr) then
 | 
			
		||||
           begin
 | 
			
		||||
             hastype:=true;
 | 
			
		||||
             Consume(AS_LPAREN);
 | 
			
		||||
             tempstr2:=actasmpattern;
 | 
			
		||||
             Consume(AS_ID);
 | 
			
		||||
             Consume(AS_RPAREN);
 | 
			
		||||
             if not SetupVar(tempstr2,false) then
 | 
			
		||||
              Message1(sym_e_unknown_id,tempstr2);
 | 
			
		||||
           end
 | 
			
		||||
          else
 | 
			
		||||
           if not SetupVar(tempstr,false) then
 | 
			
		||||
            Message1(sym_e_unknown_id,tempstr);
 | 
			
		||||
          { record.field ? }
 | 
			
		||||
          if actasmtoken=AS_DOT then
 | 
			
		||||
           begin
 | 
			
		||||
             BuildRecordOffsetSize(tempstr,l,k);
 | 
			
		||||
             inc(opr.ref.offset,l);
 | 
			
		||||
           end;
 | 
			
		||||
          case actasmtoken of
 | 
			
		||||
            AS_END,
 | 
			
		||||
            AS_SEPARATOR,
 | 
			
		||||
@ -1293,7 +1315,6 @@ var
 | 
			
		||||
var
 | 
			
		||||
  tempreg : tregister;
 | 
			
		||||
  hl      : PAsmLabel;
 | 
			
		||||
  l       : longint;
 | 
			
		||||
Begin
 | 
			
		||||
  expr:='';
 | 
			
		||||
  case actasmtoken of
 | 
			
		||||
@ -1374,47 +1395,74 @@ Begin
 | 
			
		||||
           else
 | 
			
		||||
            begin
 | 
			
		||||
              InitRef;
 | 
			
		||||
              if SetupVar(actasmpattern,false) then
 | 
			
		||||
              expr:=actasmpattern;
 | 
			
		||||
              Consume(AS_ID);
 | 
			
		||||
              { typecasting? }
 | 
			
		||||
              if (actasmtoken=AS_LPAREN) and
 | 
			
		||||
                 SearchType(expr) then
 | 
			
		||||
               begin
 | 
			
		||||
                 expr:=actasmpattern;
 | 
			
		||||
                 hastype:=true;
 | 
			
		||||
                 Consume(AS_LPAREN);
 | 
			
		||||
                 tempstr:=actasmpattern;
 | 
			
		||||
                 Consume(AS_ID);
 | 
			
		||||
                 MaybeRecordOffset;
 | 
			
		||||
                 { add a constant expression? }
 | 
			
		||||
                 if (actasmtoken=AS_PLUS) then
 | 
			
		||||
                 Consume(AS_RPAREN);
 | 
			
		||||
                 if SetupVar(tempstr,false) then
 | 
			
		||||
                  begin
 | 
			
		||||
                    l:=BuildConstExpression(true,false);
 | 
			
		||||
                    if opr.typ=OPR_CONSTANT then
 | 
			
		||||
                     inc(opr.val,l)
 | 
			
		||||
                    else
 | 
			
		||||
                     inc(opr.ref.offset,l);
 | 
			
		||||
                    MaybeRecordOffset;
 | 
			
		||||
                    { add a constant expression? }
 | 
			
		||||
                    if (actasmtoken=AS_PLUS) then
 | 
			
		||||
                     begin
 | 
			
		||||
                       l:=BuildConstExpression(true,false);
 | 
			
		||||
                       if opr.typ=OPR_CONSTANT then
 | 
			
		||||
                        inc(opr.val,l)
 | 
			
		||||
                       else
 | 
			
		||||
                        inc(opr.ref.offset,l);
 | 
			
		||||
                     end
 | 
			
		||||
                  end
 | 
			
		||||
                 else
 | 
			
		||||
                  Message1(sym_e_unknown_id,tempstr);
 | 
			
		||||
               end
 | 
			
		||||
              else
 | 
			
		||||
               Begin
 | 
			
		||||
                 { look for special symbols ... }
 | 
			
		||||
                 if actasmpattern = '__RESULT' then
 | 
			
		||||
                   SetUpResult
 | 
			
		||||
               begin
 | 
			
		||||
                 if SetupVar(expr,false) then
 | 
			
		||||
                  begin
 | 
			
		||||
                    MaybeRecordOffset;
 | 
			
		||||
                    { add a constant expression? }
 | 
			
		||||
                    if (actasmtoken=AS_PLUS) then
 | 
			
		||||
                     begin
 | 
			
		||||
                       l:=BuildConstExpression(true,false);
 | 
			
		||||
                       if opr.typ=OPR_CONSTANT then
 | 
			
		||||
                        inc(opr.val,l)
 | 
			
		||||
                       else
 | 
			
		||||
                        inc(opr.ref.offset,l);
 | 
			
		||||
                     end
 | 
			
		||||
                  end
 | 
			
		||||
                 else
 | 
			
		||||
                  if actasmpattern = '__SELF' then
 | 
			
		||||
                   SetupSelf
 | 
			
		||||
                 else
 | 
			
		||||
                  if actasmpattern = '__OLDEBP' then
 | 
			
		||||
                   SetupOldEBP
 | 
			
		||||
                 else
 | 
			
		||||
                   { check for direct symbolic names   }
 | 
			
		||||
                   { only if compiling the system unit }
 | 
			
		||||
                   if (cs_compilesystem in aktmoduleswitches) then
 | 
			
		||||
                    begin
 | 
			
		||||
                      if not SetupDirectVar(actasmpattern) then
 | 
			
		||||
                       Begin
 | 
			
		||||
                         { not found, finally ... add it anyways ... }
 | 
			
		||||
                         Message1(asmr_w_id_supposed_external,actasmpattern);
 | 
			
		||||
                         opr.ref.symbol:=newasmsymbol(actasmpattern);
 | 
			
		||||
                       end;
 | 
			
		||||
                    end
 | 
			
		||||
                 else
 | 
			
		||||
                   Message1(sym_e_unknown_id,actasmpattern);
 | 
			
		||||
                 Consume(AS_ID);
 | 
			
		||||
                  Begin
 | 
			
		||||
                    { look for special symbols ... }
 | 
			
		||||
                    if expr = '__RESULT' then
 | 
			
		||||
                      SetUpResult
 | 
			
		||||
                    else
 | 
			
		||||
                     if expr = '__SELF' then
 | 
			
		||||
                      SetupSelf
 | 
			
		||||
                    else
 | 
			
		||||
                     if expr = '__OLDEBP' then
 | 
			
		||||
                      SetupOldEBP
 | 
			
		||||
                    else
 | 
			
		||||
                      { check for direct symbolic names   }
 | 
			
		||||
                      { only if compiling the system unit }
 | 
			
		||||
                      if (cs_compilesystem in aktmoduleswitches) then
 | 
			
		||||
                       begin
 | 
			
		||||
                         if not SetupDirectVar(expr) then
 | 
			
		||||
                          Begin
 | 
			
		||||
                            { not found, finally ... add it anyways ... }
 | 
			
		||||
                            Message1(asmr_w_id_supposed_external,expr);
 | 
			
		||||
                            opr.ref.symbol:=newasmsymbol(expr);
 | 
			
		||||
                          end;
 | 
			
		||||
                       end
 | 
			
		||||
                    else
 | 
			
		||||
                      Message1(sym_e_unknown_id,expr);
 | 
			
		||||
                  end;
 | 
			
		||||
               end;
 | 
			
		||||
            end;
 | 
			
		||||
         end;
 | 
			
		||||
@ -2000,7 +2048,11 @@ begin
 | 
			
		||||
end.
 | 
			
		||||
{
 | 
			
		||||
  $Log$
 | 
			
		||||
  Revision 1.79  2000-05-18 17:05:16  peter
 | 
			
		||||
  Revision 1.80  2000-05-23 20:36:28  peter
 | 
			
		||||
    + typecasting support for variables, but be carefull as word,byte can't
 | 
			
		||||
      be used because they are reserved assembler keywords
 | 
			
		||||
 | 
			
		||||
  Revision 1.79  2000/05/18 17:05:16  peter
 | 
			
		||||
    * fixed size of const parameters in asm readers
 | 
			
		||||
 | 
			
		||||
  Revision 1.78  2000/05/12 21:57:02  pierre
 | 
			
		||||
 | 
			
		||||
@ -980,6 +980,7 @@ type
 | 
			
		||||
Procedure T386IntelOperand.BuildReference;
 | 
			
		||||
var
 | 
			
		||||
  k,l : longint;
 | 
			
		||||
  tempstr2,
 | 
			
		||||
  tempstr,hs : string;
 | 
			
		||||
  code : integer;
 | 
			
		||||
  hreg,
 | 
			
		||||
@ -1033,9 +1034,22 @@ Begin
 | 
			
		||||
             oldbase:=opr.ref.base;
 | 
			
		||||
             opr.ref.base:=R_NO;
 | 
			
		||||
             tempstr:=actasmpattern;
 | 
			
		||||
             if not SetupVar(tempstr,GotOffset) then
 | 
			
		||||
               Message1(sym_e_unknown_id,tempstr);
 | 
			
		||||
             Consume(AS_ID);
 | 
			
		||||
             { typecasting? }
 | 
			
		||||
             if (actasmtoken=AS_LPAREN) and
 | 
			
		||||
                SearchType(tempstr) then
 | 
			
		||||
              begin
 | 
			
		||||
                hastype:=true;
 | 
			
		||||
                Consume(AS_LPAREN);
 | 
			
		||||
                tempstr2:=actasmpattern;
 | 
			
		||||
                Consume(AS_ID);
 | 
			
		||||
                Consume(AS_RPAREN);
 | 
			
		||||
                if not SetupVar(tempstr2,GotOffset) then
 | 
			
		||||
                 Message1(sym_e_unknown_id,tempstr2);
 | 
			
		||||
              end
 | 
			
		||||
             else
 | 
			
		||||
              if not SetupVar(tempstr,GotOffset) then
 | 
			
		||||
               Message1(sym_e_unknown_id,tempstr);
 | 
			
		||||
             { record.field ? }
 | 
			
		||||
             if actasmtoken=AS_DOT then
 | 
			
		||||
              begin
 | 
			
		||||
@ -1228,6 +1242,7 @@ end;
 | 
			
		||||
 | 
			
		||||
Procedure T386IntelOperand.BuildOperand;
 | 
			
		||||
var
 | 
			
		||||
  tempstr,
 | 
			
		||||
  expr    : string;
 | 
			
		||||
  tempreg : tregister;
 | 
			
		||||
  l       : longint;
 | 
			
		||||
@ -1286,16 +1301,19 @@ var
 | 
			
		||||
     end;
 | 
			
		||||
    if actasmtoken in [AS_PLUS,AS_MINUS] then
 | 
			
		||||
     inc(l,BuildConstExpression);
 | 
			
		||||
    if opr.typ=OPR_REFERENCE then
 | 
			
		||||
    if (opr.typ=OPR_REFERENCE) then
 | 
			
		||||
     begin
 | 
			
		||||
       { don't allow direct access to fields of parameters, becuase that
 | 
			
		||||
         will generate buggy code }
 | 
			
		||||
       case opr.ref.options of
 | 
			
		||||
         ref_parafixup :
 | 
			
		||||
           Message(asmr_e_cannot_access_field_directly_for_parameters);
 | 
			
		||||
         ref_selffixup :
 | 
			
		||||
           Message(asmr_e_cannot_access_object_field_directly);
 | 
			
		||||
       end;
 | 
			
		||||
         will generate buggy code. Allow it only for explicit typecasting }
 | 
			
		||||
       if (not hastype) then
 | 
			
		||||
        begin
 | 
			
		||||
          case opr.ref.options of
 | 
			
		||||
            ref_parafixup :
 | 
			
		||||
              Message(asmr_e_cannot_access_field_directly_for_parameters);
 | 
			
		||||
            ref_selffixup :
 | 
			
		||||
              Message(asmr_e_cannot_access_object_field_directly);
 | 
			
		||||
          end;
 | 
			
		||||
        end;
 | 
			
		||||
       inc(opr.ref.offset,l)
 | 
			
		||||
     end
 | 
			
		||||
    else
 | 
			
		||||
@ -1379,29 +1397,56 @@ Begin
 | 
			
		||||
            { is it a normal variable ? }
 | 
			
		||||
             Begin
 | 
			
		||||
               InitRef;
 | 
			
		||||
               if SetupVar(actasmpattern,false) then
 | 
			
		||||
               expr:=actasmpattern;
 | 
			
		||||
               Consume(AS_ID);
 | 
			
		||||
               { typecasting? }
 | 
			
		||||
               if (actasmtoken=AS_LPAREN) and
 | 
			
		||||
                  SearchType(expr) then
 | 
			
		||||
                begin
 | 
			
		||||
                  expr:=actasmpattern;
 | 
			
		||||
                  hastype:=true;
 | 
			
		||||
                  Consume(AS_LPAREN);
 | 
			
		||||
                  tempstr:=actasmpattern;
 | 
			
		||||
                  Consume(AS_ID);
 | 
			
		||||
                  MaybeRecordOffset;
 | 
			
		||||
                  { add a constant expression? }
 | 
			
		||||
                  if (actasmtoken=AS_PLUS) then
 | 
			
		||||
                  Consume(AS_RPAREN);
 | 
			
		||||
                  if SetupVar(tempstr,false) then
 | 
			
		||||
                   begin
 | 
			
		||||
                     l:=BuildConstExpression;
 | 
			
		||||
                     if opr.typ=OPR_CONSTANT then
 | 
			
		||||
                      inc(opr.val,l)
 | 
			
		||||
                     else
 | 
			
		||||
                      inc(opr.ref.offset,l);
 | 
			
		||||
                     MaybeRecordOffset;
 | 
			
		||||
                     { add a constant expression? }
 | 
			
		||||
                     if (actasmtoken=AS_PLUS) then
 | 
			
		||||
                      begin
 | 
			
		||||
                        l:=BuildConstExpression;
 | 
			
		||||
                        if opr.typ=OPR_CONSTANT then
 | 
			
		||||
                         inc(opr.val,l)
 | 
			
		||||
                        else
 | 
			
		||||
                         inc(opr.ref.offset,l);
 | 
			
		||||
                      end
 | 
			
		||||
                   end
 | 
			
		||||
                  else
 | 
			
		||||
                   Message1(sym_e_unknown_id,tempstr);
 | 
			
		||||
                end
 | 
			
		||||
               else
 | 
			
		||||
                Begin
 | 
			
		||||
                  { not a variable, check special variables.. }
 | 
			
		||||
                  if actasmpattern = 'SELF' then
 | 
			
		||||
                   SetupSelf
 | 
			
		||||
                begin
 | 
			
		||||
                  if SetupVar(expr,false) then
 | 
			
		||||
                   begin
 | 
			
		||||
                     MaybeRecordOffset;
 | 
			
		||||
                     { add a constant expression? }
 | 
			
		||||
                     if (actasmtoken=AS_PLUS) then
 | 
			
		||||
                      begin
 | 
			
		||||
                        l:=BuildConstExpression;
 | 
			
		||||
                        if opr.typ=OPR_CONSTANT then
 | 
			
		||||
                         inc(opr.val,l)
 | 
			
		||||
                        else
 | 
			
		||||
                         inc(opr.ref.offset,l);
 | 
			
		||||
                      end
 | 
			
		||||
                   end
 | 
			
		||||
                  else
 | 
			
		||||
                   Message1(sym_e_unknown_id,actasmpattern);
 | 
			
		||||
                  Consume(AS_ID);
 | 
			
		||||
                   Begin
 | 
			
		||||
                     { not a variable, check special variables.. }
 | 
			
		||||
                     if expr = 'SELF' then
 | 
			
		||||
                      SetupSelf
 | 
			
		||||
                     else
 | 
			
		||||
                      Message1(sym_e_unknown_id,expr);
 | 
			
		||||
                   end;
 | 
			
		||||
                end;
 | 
			
		||||
             end;
 | 
			
		||||
           { handle references }
 | 
			
		||||
@ -1833,7 +1878,11 @@ begin
 | 
			
		||||
end.
 | 
			
		||||
{
 | 
			
		||||
  $Log$
 | 
			
		||||
  Revision 1.70  2000-05-18 17:05:16  peter
 | 
			
		||||
  Revision 1.71  2000-05-23 20:36:28  peter
 | 
			
		||||
    + typecasting support for variables, but be carefull as word,byte can't
 | 
			
		||||
      be used because they are reserved assembler keywords
 | 
			
		||||
 | 
			
		||||
  Revision 1.70  2000/05/18 17:05:16  peter
 | 
			
		||||
    * fixed size of const parameters in asm readers
 | 
			
		||||
 | 
			
		||||
  Revision 1.69  2000/05/12 21:57:02  pierre
 | 
			
		||||
 | 
			
		||||
@ -88,6 +88,7 @@ type
 | 
			
		||||
  POperand = ^TOperand;
 | 
			
		||||
  TOperand = object
 | 
			
		||||
    size   : topsize;
 | 
			
		||||
    hastype,          { if the operand has typecasted variable }
 | 
			
		||||
    hasvar : boolean; { if the operand is loaded with a variable }
 | 
			
		||||
    opr    : TOprRec;
 | 
			
		||||
    constructor init;
 | 
			
		||||
@ -184,6 +185,7 @@ Function EscapeToPascal(const s:string): string;
 | 
			
		||||
---------------------------------------------------------------------}
 | 
			
		||||
 | 
			
		||||
Function GetRecordOffsetSize(s:string;Var Offset: longint;var Size:longint):boolean;
 | 
			
		||||
Function SearchType(const hs:string): Boolean;
 | 
			
		||||
Function SearchRecordType(const s:string): boolean;
 | 
			
		||||
Function SearchIConstant(const s:string; var l:longint): boolean;
 | 
			
		||||
 | 
			
		||||
@ -649,6 +651,7 @@ end;
 | 
			
		||||
constructor TOperand.init;
 | 
			
		||||
begin
 | 
			
		||||
  size:=S_NO;
 | 
			
		||||
  hastype:=false;
 | 
			
		||||
  hasvar:=false;
 | 
			
		||||
  FillChar(Opr,sizeof(Opr),0);
 | 
			
		||||
end;
 | 
			
		||||
@ -1147,6 +1150,15 @@ end;
 | 
			
		||||
                      Symbol table helper routines
 | 
			
		||||
****************************************************************************}
 | 
			
		||||
 | 
			
		||||
Function SearchType(const hs:string): Boolean;
 | 
			
		||||
begin
 | 
			
		||||
  getsym(hs,false);
 | 
			
		||||
  SearchType:=assigned(srsym) and
 | 
			
		||||
             (srsym^.typ=typesym);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Function SearchRecordType(const s:string): boolean;
 | 
			
		||||
Begin
 | 
			
		||||
  SearchRecordType:=false;
 | 
			
		||||
@ -1516,7 +1528,11 @@ end;
 | 
			
		||||
end.
 | 
			
		||||
{
 | 
			
		||||
  $Log$
 | 
			
		||||
  Revision 1.44  2000-05-22 12:47:52  pierre
 | 
			
		||||
  Revision 1.45  2000-05-23 20:36:28  peter
 | 
			
		||||
    + typecasting support for variables, but be carefull as word,byte can't
 | 
			
		||||
      be used because they are reserved assembler keywords
 | 
			
		||||
 | 
			
		||||
  Revision 1.44  2000/05/22 12:47:52  pierre
 | 
			
		||||
   fix wrong handling of var para for size bug 961
 | 
			
		||||
 | 
			
		||||
  Revision 1.43  2000/05/18 17:05:16  peter
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user