diff --git a/compiler/ra386att.pas b/compiler/ra386att.pas index c2d1e724aa..d2c56fd097 100644 --- a/compiler/ra386att.pas +++ b/compiler/ra386att.pas @@ -2453,6 +2453,15 @@ var end; +procedure RecoverConsume(allowcomma:boolean); +begin + While not (actasmtoken in [AS_SEPARATOR,AS_END]) do + begin + if allowcomma and (actasmtoken=AS_COMMA) then + break; + Consume(actasmtoken); + end; +end; @@ -2639,49 +2648,33 @@ var -Procedure GetRecordOffsetSize(const expr: string;var offset:longint;var size:longint); -{*********************************************************************} -{ PROCEDURE GetRecordOffsetSize } +Procedure BuildRecordOffsetSize(const expr: string;var offset:longint;var size:longint); { Description: This routine builds up a record offset after a AS_DOT } { token is encountered. } { On entry actasmtoken should be equal to AS_DOT } -{*********************************************************************} -{ EXIT CONDITION: On exit the routine should point to either the } -{ ERROR RECOVER: read until AS_COMMA or AS_SEPARATOR token. } -{ Warning: This is called recursively. } -{*********************************************************************} var - toffset,tsize : longint; + s : string; Begin offset:=0; size:=0; - Consume(AS_DOT); - if actasmtoken = AS_ID then - Begin - if not GetTypeOffsetSize(expr,actasmpattern,toffset,tsize) and - not GetVarOffsetSize(expr,actasmpattern,toffset,tsize) then + s:=expr; + while (actasmtoken=AS_DOT) do + begin + Consume(AS_DOT); + if actasmtoken=AS_ID then + begin + s:=s+'.'+actasmpattern; + Consume(AS_ID); + end + else begin Message(assem_e_syntax_error); - toffset:=0; - tsize:=0; + RecoverConsume(true); + break; end; - inc(offset,toffset); - size:=tsize; - Consume(AS_ID); - if actasmtoken=AS_DOT then - begin - GetRecordOffsetSize(expr,toffset,tsize); - inc(offset,toffset); - size:=tsize; - end; - end - else - Begin - Message(assem_e_syntax_error); - repeat - consume(actasmtoken) - until (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA); end; + if not GetRecordOffsetSize(s,offset,size) then + Message(assem_e_syntax_error); end; @@ -2815,7 +2808,7 @@ Begin consume(AS_ID); if actasmtoken=AS_DOT then begin - GetRecordOffsetSize(tempstr,l,k); + BuildRecordOffsetSize(tempstr,l,k); str(l, tempstr); expr := expr + tempstr; end @@ -3350,7 +3343,7 @@ Begin Consume(AS_ID); if actasmtoken=AS_DOT then begin - GetRecordOffsetSize(expr,toffset,tsize); + BuildRecordOffsetSize(expr,toffset,tsize); inc(instr.operands[operandnum].ref.offset,toffset); SetOperandSize(instr,operandnum,tsize); end; @@ -3967,7 +3960,11 @@ end. { $Log$ - Revision 1.38 1999-04-21 21:42:22 pierre + Revision 1.39 1999-04-26 23:26:12 peter + * redesigned record offset parsing to support nested records + * normal compiler uses the redesigned createvarinstr() + + Revision 1.38 1999/04/21 21:42:22 pierre * wrong log for v1.37 corrected Revision 1.37 1999/04/21 16:31:41 pierre diff --git a/compiler/ra386int.pas b/compiler/ra386int.pas index dd77617d68..0ce6d9e29e 100644 --- a/compiler/ra386int.pas +++ b/compiler/ra386int.pas @@ -1893,8 +1893,15 @@ var actasmtoken := gettoken; end; - - +procedure RecoverConsume(allowcomma:boolean); +begin + While not (actasmtoken in [AS_SEPARATOR,AS_END]) do + begin + if allowcomma and (actasmtoken=AS_COMMA) then + break; + Consume(actasmtoken); + end; +end; function findregister(const s : string): tregister; @@ -2077,50 +2084,33 @@ var End; - -Procedure GetRecordOffsetSize(const expr: string;var offset:longint;var size:longint); -{*********************************************************************} -{ PROCEDURE GetRecordOffsetSize } -{ Description: This routine builds up a record offset after a AS_DOT } -{ token is encountered. } -{ On entry actasmtoken should be equal to AS_DOT } -{*********************************************************************} -{ EXIT CONDITION: On exit the routine should point to either the } -{ ERROR RECOVER: read until AS_COMMA or AS_SEPARATOR token. } -{ Warning: This is called recursively. } -{*********************************************************************} +Procedure BuildRecordOffsetSize(const expr: string;var offset:longint;var size:longint); +{ Description: This routine builds up a record offset after a AS_DOT } +{ token is encountered. } +{ On entry actasmtoken should be equal to AS_DOT } var - toffset,tsize : longint; + s : string; Begin offset:=0; size:=0; - Consume(AS_DOT); - if actasmtoken = AS_ID then - Begin - if not GetTypeOffsetSize(expr,actasmpattern,toffset,tsize) and - not GetVarOffsetSize(expr,actasmpattern,toffset,tsize) then + s:=expr; + while (actasmtoken=AS_DOT) do + begin + Consume(AS_DOT); + if actasmtoken=AS_ID then + begin + s:=s+'.'+actasmpattern; + Consume(AS_ID); + end + else begin Message(assem_e_syntax_error); - toffset:=0; - tsize:=0; + RecoverConsume(true); + break; end; - inc(offset,toffset); - size:=tsize; - Consume(AS_ID); - if actasmtoken=AS_DOT then - begin - GetRecordOffsetSize(expr,toffset,tsize); - inc(offset,toffset); - size:=tsize; - end; - end - else - Begin - Message(assem_e_syntax_error); - repeat - consume(actasmtoken) - until (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA); end; + if not GetRecordOffsetSize(s,offset,size) then + Message(assem_e_syntax_error); end; @@ -2243,7 +2233,7 @@ Begin consume(AS_ID); if actasmtoken=AS_DOT then begin - GetRecordOffsetSize(tempstr,l,k); + BuildRecordOffsetSize(tempstr,l,k); str(l, tempstr); expr := expr + tempstr; end @@ -2321,7 +2311,7 @@ end; { var_name.typefield.typefield } if (varname <> '') then Begin - if GetVarOffsetSize(varname,actasmpattern,toffset,tsize) then + if GetRecordOffsetSize(varname+'.'+actasmpattern,toffset,tsize) then Begin Inc(instr.operands[operandnum].ref.offset,tOffset); SetOperandSize(instr,operandnum,tsize); @@ -2355,7 +2345,7 @@ end; { [ref].typefield.typefield ... } { basetpyename is already set up... now look for fields. } Begin - if GetTypeOffsetSize(basetypename,actasmpattern,tOffset,Tsize) then + if GetRecordOffsetSize(basetypename+'.'+actasmpattern,tOffset,Tsize) then Begin Inc(instr.operands[operandnum].ref.offset,tOffset); SetOperandSize(instr,operandnum,Tsize); @@ -2486,7 +2476,7 @@ end; consume(AS_ID); if actasmtoken=AS_DOT then begin - GetRecordOffsetSize(tempstr,l,k); + BuildRecordOffsetSize(tempstr,l,k); str(l, tempstr); expr := expr + tempstr; end @@ -2831,7 +2821,7 @@ end; var l:longint; again : boolean; - + Begin Consume(AS_LBRACKET); initAsmRef(instr); @@ -3629,7 +3619,11 @@ begin end. { $Log$ - Revision 1.29 1999-04-19 09:44:26 pierre + Revision 1.30 1999-04-26 23:26:13 peter + * redesigned record offset parsing to support nested records + * normal compiler uses the redesigned createvarinstr() + + Revision 1.29 1999/04/19 09:44:26 pierre * accept several previously refused syntax, still uncomplete Revision 1.28 1999/04/18 00:32:23 pierre diff --git a/compiler/rautils.pas b/compiler/rautils.pas index 3f7703ccf6..93ad22b9ed 100644 --- a/compiler/rautils.pas +++ b/compiler/rautils.pas @@ -277,8 +277,7 @@ Type {---------------------------------------------------------------------} Procedure SetOperandSize(var instr:TInstruction;operandnum,size:longint); - Function GetVarOffsetSize(const base,field:string;Var Offset: longint;var Size:longint):boolean; - Function GetTypeOffsetSize(const base,field: string;Var Offset: longint;var Size:longint):boolean; +Function GetRecordOffsetSize(s:string;Var Offset: longint;var Size:longint):boolean; Function SearchIConstant(const s:string; var l:longint): boolean; Function SearchLabel(const s: string; var hl: plabel): boolean; Function CreateVarInstr(var Instr: TInstruction; const hs:string; @@ -1087,485 +1086,189 @@ end; end; - Function GetVarOffsetSize(const base,field:string;Var Offset: longint;var Size:longint):boolean; - { search and returns the offset and size of records/objects of the base } - { with field name setup in field. } - { returns FALSE if not found. } - { used when base is a variable or a typed constant name. } - var - sym:psym; - p: psym; - Begin - GetVarOffsetSize := FALSE; - Offset := 0; - { local list } - if assigned(aktprocsym) then - begin - if assigned(aktprocsym^.definition^.localst) then - sym:=aktprocsym^.definition^.localst^.search(base) - else - sym:=nil; - if assigned(sym) then +Function GetRecordOffsetSize(s:string;Var Offset: longint;var Size:longint):boolean; +{ search and returns the offset and size of records/objects of the base } +{ with field name setup in field. } +{ returns FALSE if not found. } +{ used when base is a variable or a typed constant name. } +var + st : psymtable; + sym : psym; + i : longint; + base : string; +Begin + GetRecordOffsetSize := FALSE; + Offset:=0; + Size:=0; + i:=pos('.',s); + if i=0 then + i:=255; + base:=Copy(s,1,i-1); + delete(s,1,i); + getsym(base,false); + sym:=srsym; + st:=nil; + { we can start with a var,type,typedconst } + case sym^.typ of + varsym : begin - { field of local record variable. } - if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=recorddef) then - begin - p:=pvarsym(precdef(pvarsym(sym)^.definition)^.symtable^.search(field)); - if assigned(pvarsym(p)) then - Begin - Offset := pvarsym(p)^.address; - Size:=PVarsym(p)^.getsize; - GetVarOffsetSize := TRUE; - Exit; - end; - end - else - if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=objectdef) then - begin - if assigned(pobjectdef(pvarsym(sym)^.definition)^.publicsyms) then - begin - p:=pvarsym(pobjectdef(pvarsym(sym)^.definition)^.publicsyms^.search(field)); - if assigned(pvarsym(p)) then - Begin - Offset := pvarsym(p)^.address; - Size:=PVarsym(p)^.getsize; - GetVarOffsetSize := TRUE; - Exit; - end; - end; - end; - end - else - begin - { field of local record parameter to routine. } - if assigned(aktprocsym^.definition^.parast) then - sym:=aktprocsym^.definition^.parast^.search(base) - else - sym:=nil; - if assigned(sym) then + case pvarsym(sym)^.definition^.deftype of + recorddef : + st:=precdef(pvarsym(sym)^.definition)^.symtable; + objectdef : + st:=pobjectdef(pvarsym(sym)^.definition)^.publicsyms; + end; + end; + typesym : + begin + case ptypesym(sym)^.definition^.deftype of + recorddef : + st:=precdef(ptypesym(sym)^.definition)^.symtable; + objectdef : + st:=pobjectdef(ptypesym(sym)^.definition)^.publicsyms; + end; + end; + typedconstsym : + begin + case pvarsym(sym)^.definition^.deftype of + recorddef : + st:=precdef(ptypedconstsym(sym)^.definition)^.symtable; + objectdef : + st:=pobjectdef(ptypedconstsym(sym)^.definition)^.publicsyms; + end; + end; + end; + { now walk all recordsymtables } + while assigned(st) and (s<>'') do + begin + { load next field in base } + i:=pos('.',s); + if i=0 then + i:=255; + base:=Copy(s,1,i-1); + delete(s,1,i); + sym:=st^.search(base); + st:=nil; + case sym^.typ of + varsym : begin - if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=recorddef) - then - begin - p:=pvarsym(precdef(pvarsym(sym)^.definition)^.symtable^.search(field)); - if assigned(p) then - Begin - Offset := pvarsym(p)^.address; - Size:=PVarsym(p)^.getsize; - GetVarOffsetSize := TRUE; - Exit; - end; - end { endif } - else - if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=objectdef) then - begin - if assigned(pobjectdef(pvarsym(sym)^.definition)^.publicsyms) then - begin - p:=pvarsym(pobjectdef(pvarsym(sym)^.definition)^.publicsyms^.search(field)); - if assigned(pvarsym(p)) then - Begin - Offset := pvarsym(p)^.address; - Size:=PVarsym(p)^.getsize; - GetVarOffsetSize := TRUE; - Exit; - end; - end; - end; + inc(Offset,pvarsym(sym)^.address); + Size:=PVarsym(sym)^.getsize; + case pvarsym(sym)^.definition^.deftype of + recorddef : + st:=precdef(pvarsym(sym)^.definition)^.symtable; + objectdef : + st:=pobjectdef(pvarsym(sym)^.definition)^.publicsyms; + end; end; - end; - end; { endif assigned(aktprocsym) } - - { not found.. .now look for global variables. } - getsym(base,false); - sym:=srsym; - if assigned(sym) then - Begin - { field of global record variable. } - if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=recorddef) then - begin - p:=pvarsym(precdef(pvarsym(sym)^.definition)^.symtable^.search(field)); - if assigned(p) then - Begin - Offset := pvarsym(p)^.address; - Size:=PVarsym(p)^.getsize; - GetVarOffsetSize := TRUE; - Exit; - end; - end - else - { field of global record type constant. } - if (sym^.typ=typedconstsym) and (ptypedconstsym(sym)^.definition^.deftype=recorddef) - then - begin - p:=pvarsym(precdef(pvarsym(sym)^.definition)^.symtable^.search(field)); - if assigned(p) then - Begin - Offset := pvarsym(p)^.address; - Size:=PVarsym(p)^.getsize; - GetVarOffsetSize := TRUE; - Exit; - end; - end - else - if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=objectdef) then - begin - if assigned(pobjectdef(pvarsym(sym)^.definition)^.publicsyms) then - begin - p:=pvarsym(pobjectdef(pvarsym(sym)^.definition)^.publicsyms^.search(field)); - if assigned(pvarsym(p)) then - Begin - Offset := pvarsym(p)^.address; - Size:=PVarsym(p)^.getsize; - GetVarOffsetSize := TRUE; - Exit; - end; - end; - end; - end; { end looking for global variables .. } - end; + end; + end; + GetRecordOffsetSize:=(s=''); +end; - - Function GetTypeOffsetSize(const base,field: string;Var Offset: longint;var Size:longint):boolean; - { search and returns the offset of records/objects of the base } - { with field name setup in field. } - { returns 0 if not found. } - { used when base is a variable or a typed constant name. } - var - sym:psym; - p: psym; - Begin - Offset := 0; - GetTypeOffsetSize := FALSE; - { local list } - if assigned(aktprocsym) then - begin - if assigned(aktprocsym^.definition^.localst) then - sym:=aktprocsym^.definition^.localst^.search(base) - else - sym:=nil; - if assigned(sym) then +Function CreateVarInstr(var Instr: TInstruction; const hs:string;operandnum:byte): Boolean; +{ search and sets up the correct fields in the Instr record } +{ for the NON-constant identifier passed to the routine. } +{ if not found returns FALSE. } +var + sym : psym; +Begin + CreateVarInstr := FALSE; +{ are we in a routine ? } + getsym(hs,false); + sym:=srsym; + if sym=nil then + exit; + case sym^.typ of + varsym : begin - { field of local record type. } - if (sym^.typ=typesym) and (ptypesym(sym)^.definition^.deftype=recorddef) then - begin - p:=precdef(ptypesym(sym)^.definition)^.symtable^.search(field); - if assigned(p) then - Begin - Offset := pvarsym(p)^.address; - Size:=PVarsym(p)^.getsize; - GetTypeOffsetSize := TRUE; - Exit; - end; - end; - end - else - begin - { field of local record type to routine. } - if assigned(aktprocsym^.definition^.parast) then - sym:=aktprocsym^.definition^.parast^.search(base) - else - sym:=nil; - if assigned(sym) then + { we always assume in asm statements that } + { that the variable is valid. } + pvarsym(sym)^.is_valid:=1; + inc(pvarsym(sym)^.refs); + case pvarsym(sym)^.owner^.symtabletype of + unitsymtable, + globalsymtable, + staticsymtable : + instr.operands[operandnum].ref.symbol:=newasmsymbol(pvarsym(sym)^.mangledname); + parasymtable : + begin + instr.operands[operandnum].ref.base := procinfo.framepointer; + instr.operands[operandnum].ref.offset := pvarsym(sym)^.address+aktprocsym^.definition^.parast^.address_fixup; + end; + localsymtable : + begin + if (pvarsym(sym)^.var_options and vo_is_external)<>0 then + instr.operands[operandnum].ref.symbol:=newasmsymbol(pvarsym(sym)^.mangledname) + else + begin + instr.operands[operandnum].ref.base := procinfo.framepointer; + instr.operands[operandnum].ref.offset := -(pvarsym(sym)^.address); + end; + end; + end; + case pvarsym(sym)^.definition^.deftype of + orddef, + enumdef, + floatdef : + SetOperandSize(instr,operandnum,pvarsym(sym)^.getsize); + arraydef : + SetOperandSize(instr,operandnum,parraydef(pvarsym(sym)^.definition)^.elesize) + end; + CreateVarInstr := TRUE; + Exit; + end; + typedconstsym : + begin + instr.operands[operandnum].ref.symbol:=newasmsymbol(ptypedconstsym(sym)^.mangledname); + case ptypedconstsym(sym)^.definition^.deftype of + orddef, + enumdef, + floatdef : + SetOperandSize(instr,operandnum,ptypedconstsym(sym)^.getsize); + arraydef : + SetOperandSize(instr,operandnum,parraydef(ptypedconstsym(sym)^.definition)^.elesize) + end; + CreateVarInstr := TRUE; + Exit; + end; + constsym : + begin + if pconstsym(sym)^.consttype in [constint,constchar,constbool] then begin - if (sym^.typ=typesym) and (ptypesym(sym)^.definition^.deftype=recorddef) - then - begin - p:=precdef(ptypesym(sym)^.definition)^.symtable^.search(field); - if assigned(p) then - Begin - Offset := pvarsym(p)^.address; - GetTypeOffsetSize := TRUE; - Exit; - end; - end; { endif } - end; {endif } - end; { endif } - end; - - { not found.. .now look for global types. } - getsym(base,false); - sym:=srsym; - if assigned(sym) then - Begin - { field of global record types. } - if (sym^.typ=typesym) and (ptypesym(sym)^.definition^.deftype=recorddef) then - begin - p:=precdef(ptypesym(sym)^.definition)^.symtable^.search(field); - if assigned(p) then - Begin - Offset := pvarsym(p)^.address; - Size:=PVarsym(p)^.getsize; - GetTypeOffsetSize := TRUE; - Exit; - end - end - else - { public field names of objects } - if (sym^.typ=typesym) and (ptypesym(sym)^.definition^.deftype=objectdef)then - begin - if assigned(pobjectdef(ptypesym(sym)^.definition)^.publicsyms) then - Begin - p:=pobjectdef(ptypesym(sym)^.definition)^.publicsyms^.search(field); - if assigned(p) then - Begin - Offset := pvarsym(p)^.address; - Size:=PVarsym(p)^.getsize; - GetTypeOffsetSize := TRUE; - Exit; - end - end; - end; - end; { end looking for global variables .. } + instr.operands[operandnum].operandtype:=OPR_CONSTANT; + instr.operands[operandnum].val:=pconstsym(sym)^.value; + CreateVarInstr := TRUE; + Exit; + end; + end; + typesym : + begin + if ptypesym(sym)^.definition^.deftype in [recorddef,objectdef] then + begin + instr.operands[operandnum].operandtype:=OPR_CONSTANT; + instr.operands[operandnum].val:=0; + CreateVarInstr := TRUE; + Exit; + end; + end; + procsym : + begin + if assigned(pprocsym(sym)^.definition^.nextoverloaded) then + Message(assem_w_calling_overload_func); + instr.operands[operandnum].operandtype:=OPR_SYMBOL; + instr.operands[operandnum].symbol:=newasmsymbol(pprocsym(sym)^.definition^.mangledname); + CreateVarInstr := TRUE; + Exit; + end; + else + begin + Message(assem_e_unsupported_symbol_type); + exit; + end; end; - - - Function CreateVarInstr(var Instr: TInstruction; const hs:string;operandnum:byte): Boolean; - { search and sets up the correct fields in the Instr record } - { for the NON-constant identifier passed to the routine. } - { if not found returns FALSE. } - var - sym : psym; - l : longint; - Begin - CreateVarInstr := FALSE; - { are we in a routine ? } - if assigned(aktprocsym) then - begin - { search the local list for the name of this variable. } - if assigned(aktprocsym^.definition^.localst) then - sym:=aktprocsym^.definition^.localst^.search(hs) - else - sym:=nil; - if assigned(sym) then - begin - case sym^.typ of - varsym : begin - { we always assume in asm statements that } - { that the variable is valid. } - pvarsym(sym)^.is_valid:=1; - inc(pvarsym(sym)^.refs); - if (pvarsym(sym)^.owner^.symtabletype=staticsymtable) or - ((pvarsym(sym)^.var_options and vo_is_external)<>0) then - begin - instr.operands[operandnum].ref.symbol:=newasmsymbol(pvarsym(sym)^.mangledname); - end - else - begin - instr.operands[operandnum].ref.base := procinfo.framepointer; - instr.operands[operandnum].ref.offset := -(pvarsym(sym)^.address); - end; - { the current size is NOT overriden if it already } - { exists, such as in the case of a byte ptr, in } - { front of the identifier. } - if (instr.operands[operandnum].size = S_NO) or (instr.operands[operandnum].overriden = FALSE) then - Begin - case pvarsym(sym)^.getsize of - 1: instr.operands[operandnum].size := S_B; - 2: instr.operands[operandnum].size := S_W{ could be S_IS}; - 4: instr.operands[operandnum].size := S_L{ could be S_IL or S_FS}; - 8: instr.operands[operandnum].size := S_IQ{ could be S_D or S_FL}; - extended_size: instr.operands[operandnum].size := S_FX; - else - { this is in the case where the instruction is LEA } - { or something like that, in that case size is not } - { important. } - instr.operands[operandnum].size := S_NO; - end; { end case } - end; - { ok, finished for this var } - CreateVarInstr := TRUE; - Exit; - end; - typedconstsym : begin - { we always assume in asm statements that } - { that the variable is valid. } - instr.operands[operandnum].ref.symbol:=newasmsymbol(pvarsym(sym)^.mangledname); - { the current size is NOT overriden if it already } - { exists, such as in the case of a byte ptr, in } - { front of the identifier. } - if (instr.operands[operandnum].size = S_NO) or (instr.operands[operandnum].overriden = FALSE) then - Begin - case ptypedconstsym(sym)^.getsize of - 1: instr.operands[operandnum].size := S_B; - 2: instr.operands[operandnum].size := S_W{ could be S_IS}; - 4: instr.operands[operandnum].size := S_L{ could be S_IL or S_FS}; - 8: instr.operands[operandnum].size := S_IQ{ could be S_D or S_FL}; - extended_size: instr.operands[operandnum].size := S_FX; - else - instr.operands[operandnum].size := S_NO; - end; { end case } - end; - { ok, finished for this var } - CreateVarInstr := TRUE; - Exit; - end; - constsym : begin - if pconstsym(sym)^.consttype in [constint,constchar,constbool] then - begin - instr.operands[operandnum].operandtype:=OPR_CONSTANT; - instr.operands[operandnum].val:=pconstsym(sym)^.value; - CreateVarInstr := TRUE; - Exit; - end; - end; - typesym : begin - if ptypesym(sym)^.definition^.deftype in [recorddef,objectdef] then - begin - instr.operands[operandnum].operandtype:=OPR_CONSTANT; - instr.operands[operandnum].val:=0; - CreateVarInstr := TRUE; - Exit; - end; - end; - procsym : begin - instr.operands[operandnum].operandtype:=OPR_SYMBOL; - instr.operands[operandnum].symbol:=newasmsymbol(pprocsym(sym)^.definition^.mangledname); - CreateVarInstr := TRUE; - Exit; - end - else - begin - Message(assem_e_unsupported_symbol_type); - exit; - end; - end; - end; - - { now check for parameters passed to routine } - if assigned(aktprocsym^.definition^.parast) then - sym:=aktprocsym^.definition^.parast^.search(hs) - else - sym:=nil; - if assigned(sym) then - begin - case sym^.typ of - varsym : begin - if pvarsym(sym)^.islocalcopy then - l:=-pvarsym(sym)^.address - else - begin - l:=pvarsym(sym)^.address; - { set offset } - inc(l,aktprocsym^.definition^.parast^.address_fixup); - end; - pvarsym(sym)^.is_valid:=1; - inc(pvarsym(sym)^.refs); - instr.operands[operandnum].ref.base := procinfo.framepointer; - instr.operands[operandnum].ref.offset := l; - { the current size is NOT overriden if it already } - { exists, such as in the case of a byte ptr, in } - { front of the identifier. } - if (instr.operands[operandnum].size = S_NO) or (instr.operands[operandnum].overriden = FALSE) then - Begin - case pvarsym(sym)^.getsize of - 1: instr.operands[operandnum].size := S_B; - 2: instr.operands[operandnum].size := S_W; - 4: instr.operands[operandnum].size := S_L; - 8: instr.operands[operandnum].size := S_IQ; - extended_size: instr.operands[operandnum].size := S_FX; - else - { this is in the case where the instruction is LEA } - { or something like that, in that case size is not } - { important. } - instr.operands[operandnum].size := S_NO; - end; { end case } - end; { endif } - CreateVarInstr := TRUE; - Exit; - end; - else - begin - Message(assem_e_unsupported_symbol_type); - exit; - end; - end; { case } - end; { endif } - end; - { not found.. .now look for global variables. } - getsym(hs,false); - sym:=srsym; - if assigned(sym) then - Begin - case sym^.typ of - varsym, - typedconstsym : Begin - if sym^.typ=varsym then - inc(pvarsym(sym)^.refs); - instr.operands[operandnum].ref.symbol:=newasmsymbol(sym^.mangledname); - { the current size is NOT overriden if it already } - { exists, such as in the case of a byte ptr, in } - { front of the identifier. } - if (instr.operands[operandnum].size = S_NO) or (instr.operands[operandnum].overriden = FALSE) then - Begin - case pvarsym(sym)^.getsize of - 1: instr.operands[operandnum].size := S_B; - 2: instr.operands[operandnum].size := S_W; - 4: instr.operands[operandnum].size := S_L; - 8: instr.operands[operandnum].size := S_IQ; - else - { this is in the case where the instruction is LEA } - { or something like that, in that case size is not } - { important. } - instr.operands[operandnum].size := S_NO; - end; - end - else - if (instr.operands[operandnum].size = S_NO) and (sym^.typ = typedconstsym) then - Begin - { only these are valid sizes, otherwise prefixes are } - { required. } - case ptypedconstsym(sym)^.definition^.size of - 1: instr.operands[operandnum].size := S_B; - 2: instr.operands[operandnum].size := S_W; - 4: instr.operands[operandnum].size := S_L; - 8: instr.operands[operandnum].size := S_IQ; - else - { this is in the case where the instruction is LEA } - { or something like that, in that case size is not } - { important. } - instr.operands[operandnum].size := S_NO; - end; - end; { endif } - CreateVarInstr := TRUE; - Exit; - end; - constsym : begin - if pconstsym(sym)^.consttype in [constint,constchar,constbool] then - begin - instr.operands[operandnum].operandtype:=OPR_CONSTANT; - instr.operands[operandnum].val:=pconstsym(sym)^.value; - CreateVarInstr := TRUE; - Exit; - end; - end; - typesym : begin - if ptypesym(sym)^.definition^.deftype in [recorddef,objectdef] then - begin - instr.operands[operandnum].operandtype:=OPR_CONSTANT; - instr.operands[operandnum].val:=0; - CreateVarInstr := TRUE; - Exit; - end; - end; - procsym : begin - if assigned(pprocsym(sym)^.definition^.nextoverloaded) then - Message(assem_w_calling_overload_func); - instr.operands[operandnum].operandtype:=OPR_SYMBOL; - instr.operands[operandnum].size:=S_L; - instr.operands[operandnum].symbol:=newasmsymbol(pprocsym(sym)^.definition^.mangledname); - CreateVarInstr := TRUE; - Exit; - end; - else - begin - Message(assem_e_unsupported_symbol_type); - exit; - end; - end; {case} - end; { end looking for global variables .. } - end; - +end; Function SearchLabel(const s: string; var hl: plabel): boolean; @@ -1791,7 +1494,11 @@ end; end. { $Log$ - Revision 1.8 1999-03-31 13:55:19 peter + Revision 1.9 1999-04-26 23:26:14 peter + * redesigned record offset parsing to support nested records + * normal compiler uses the redesigned createvarinstr() + + Revision 1.8 1999/03/31 13:55:19 peter * assembler inlining working for ag386bin Revision 1.7 1999/03/24 23:17:23 peter