|
@@ -26,44 +26,185 @@ Unit rax64int;
|
|
|
interface
|
|
|
|
|
|
uses
|
|
|
+ aasmtai,
|
|
|
rax86int;
|
|
|
|
|
|
type
|
|
|
tx8664intreader = class(tx86intreader)
|
|
|
- // procedure handleopcode;override;
|
|
|
+ actsehdirective: TAsmSehDirective;
|
|
|
+ function is_targetdirective(const s:string):boolean;override;
|
|
|
+ procedure HandleTargetDirective;override;
|
|
|
end;
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
uses
|
|
|
- rabase,systems;
|
|
|
+ globtype,
|
|
|
+ cutils,
|
|
|
+ systems,
|
|
|
+ verbose,
|
|
|
+ cgbase,
|
|
|
+ symconst,
|
|
|
+ procinfo,
|
|
|
+ rabase;
|
|
|
|
|
|
-(*
|
|
|
- procedure tx8664intreader.handleopcode;
|
|
|
+ const
|
|
|
+ { x86_64 subset of SEH directives. .seh_proc and .seh_endproc excluded
|
|
|
+ because they are generated automatically when needed. }
|
|
|
+ recognized_directives: set of TAsmSehDirective=[
|
|
|
+ ash_endprologue,ash_handler,ash_handlerdata,
|
|
|
+ ash_setframe,ash_stackalloc,ash_pushreg,
|
|
|
+ ash_savereg,ash_savexmm,ash_pushframe{,
|
|
|
+ ash_pushnv,ash_savenv }
|
|
|
+ ];
|
|
|
+
|
|
|
+ { max offset and bitmask for .seh_savereg and .seh_setframe }
|
|
|
+ maxoffset: array[boolean] of aint=(high(dword), 240);
|
|
|
+ modulo: array[boolean] of integer=(7, 15);
|
|
|
+
|
|
|
+ function tx8664intreader.is_targetdirective(const s:string):boolean;
|
|
|
+ var
|
|
|
+ i: TAsmSehDirective;
|
|
|
+ begin
|
|
|
+ result:=false;
|
|
|
+ if target_info.system<>system_x86_64_win64 then exit;
|
|
|
+
|
|
|
+ for i:=low(TAsmSehDirective) to high(TAsmSehDirective) do
|
|
|
+ begin
|
|
|
+ if not (i in recognized_directives) then
|
|
|
+ continue;
|
|
|
+ if s=sehdirectivestr[i] then
|
|
|
+ begin
|
|
|
+ actsehdirective:=i;
|
|
|
+ result:=true;
|
|
|
+ break;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ { allow SEH directives only in pure assember routines }
|
|
|
+ if result and not (po_assembler in current_procinfo.procdef.procoptions) then
|
|
|
+ begin
|
|
|
+ Message(asmr_e_seh_in_pure_asm_only);
|
|
|
+ result:=false;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tx8664intreader.HandleTargetDirective;
|
|
|
var
|
|
|
- instr : Tx86Instruction;
|
|
|
+ hreg: TRegister;
|
|
|
+ hnum: aint;
|
|
|
+ flags: integer;
|
|
|
+ ai: tai_seh_directive;
|
|
|
+ hs: string;
|
|
|
+ err: boolean;
|
|
|
begin
|
|
|
- instr:=Tx86Instruction.Create(Tx86Operand);
|
|
|
- instr.OpOrder:=op_att;
|
|
|
- BuildOpcode(instr);
|
|
|
- instr.AddReferenceSizes;
|
|
|
- instr.SetInstructionOpsize;
|
|
|
- {
|
|
|
- instr.CheckOperandSizes;
|
|
|
- }
|
|
|
- instr.ConcatInstruction(curlist);
|
|
|
- instr.Free;
|
|
|
+ if actasmtoken<>AS_TARGET_DIRECTIVE then
|
|
|
+ InternalError(2011100201);
|
|
|
+ Consume(AS_TARGET_DIRECTIVE);
|
|
|
+ Include(current_procinfo.flags,pi_has_unwind_info);
|
|
|
+ case actsehdirective of
|
|
|
+ { TODO: .seh_pushframe is supposed to have a boolean parameter,
|
|
|
+ but GAS 2.21 does not support it. }
|
|
|
+ ash_endprologue,
|
|
|
+ ash_pushframe,
|
|
|
+ ash_handlerdata:
|
|
|
+ curlist.concat(cai_seh_directive.create(actsehdirective));
|
|
|
+ ash_handler:
|
|
|
+ begin
|
|
|
+ hs:=actasmpattern;
|
|
|
+ Consume(AS_ID);
|
|
|
+ flags:=0;
|
|
|
+ err:=false;
|
|
|
+ while actasmtoken=AS_COMMA do
|
|
|
+ begin
|
|
|
+ Consume(AS_COMMA);
|
|
|
+ if actasmtoken=AS_ID then
|
|
|
+ begin
|
|
|
+ uppervar(actasmpattern);
|
|
|
+ if actasmpattern='@EXCEPT' then
|
|
|
+ flags:=flags or 1
|
|
|
+ else if actasmpattern='@UNWIND' then
|
|
|
+ flags:=flags or 2
|
|
|
+ else
|
|
|
+ err:=true;
|
|
|
+ Consume(AS_ID);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ err:=true;
|
|
|
+ if err then
|
|
|
+ begin
|
|
|
+ Message(asmr_e_syntax_error);
|
|
|
+ RecoverConsume(false);
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ ai:=cai_seh_directive.create_name(ash_handler,hs);
|
|
|
+ ai.data.flags:=flags;
|
|
|
+ curlist.concat(ai);
|
|
|
+ end;
|
|
|
+ ash_stackalloc:
|
|
|
+ begin
|
|
|
+ hnum:=BuildConstExpression;//(false,false);
|
|
|
+ if (hnum<0) or (hnum>high(dword)) or ((hnum and 7)<>0) then
|
|
|
+ Message1(asmr_e_bad_seh_directive_offset,sehdirectivestr[ash_stackalloc])
|
|
|
+ else
|
|
|
+ curlist.concat(cai_seh_directive.create_offset(ash_stackalloc,hnum));
|
|
|
+ end;
|
|
|
+ //ash_pushnv,
|
|
|
+ ash_pushreg:
|
|
|
+ begin
|
|
|
+ hreg:=actasmregister;
|
|
|
+ Consume(AS_REGISTER);
|
|
|
+ if (getregtype(hreg)<>R_INTREGISTER) or (getsubreg(hreg)<>R_SUBQ) then
|
|
|
+ Message1(asmr_e_bad_seh_directive_register,sehdirectivestr[ash_pushreg])
|
|
|
+ else
|
|
|
+ curlist.concat(cai_seh_directive.create_reg(ash_pushreg,hreg));
|
|
|
+ end;
|
|
|
+ ash_setframe,
|
|
|
+ ash_savereg:
|
|
|
+ begin
|
|
|
+ hreg:=actasmregister;
|
|
|
+ Consume(AS_REGISTER);
|
|
|
+ if (getregtype(hreg)<>R_INTREGISTER) or (getsubreg(hreg)<>R_SUBQ) then
|
|
|
+ Message1(asmr_e_bad_seh_directive_register,sehdirectivestr[actsehdirective]);
|
|
|
+ Consume(AS_COMMA);
|
|
|
+ hnum:=BuildConstExpression;//(false,false);
|
|
|
+ if (hnum<0) or (hnum>maxoffset[actsehdirective=ash_setframe]) or
|
|
|
+ ((hnum mod modulo[actsehdirective=ash_setframe])<>0) then
|
|
|
+ Message1(asmr_e_bad_seh_directive_offset,sehdirectivestr[actsehdirective])
|
|
|
+ else
|
|
|
+ curlist.concat(cai_seh_directive.create_reg_offset(actsehdirective,hreg,hnum));
|
|
|
+ end;
|
|
|
+ //ash_savenv,
|
|
|
+ ash_savexmm:
|
|
|
+ begin
|
|
|
+ hreg:=actasmregister;
|
|
|
+ Consume(AS_REGISTER);
|
|
|
+ if (getregtype(hreg)<>R_MMREGISTER) then
|
|
|
+ Message1(asmr_e_bad_seh_directive_register,sehdirectivestr[ash_savexmm]);
|
|
|
+ Consume(AS_COMMA);
|
|
|
+ hnum:=BuildConstExpression;//(false,false);
|
|
|
+ if (hnum<0) or (hnum>high(dword)) or ((hnum and 15)<>0) then
|
|
|
+ Message1(asmr_e_bad_seh_directive_offset,sehdirectivestr[ash_savexmm])
|
|
|
+ else
|
|
|
+ curlist.concat(cai_seh_directive.create_reg_offset(actsehdirective,hreg,hnum));
|
|
|
+ end;
|
|
|
+ else
|
|
|
+ InternalError(2018022401);
|
|
|
+ end;
|
|
|
+ if actasmtoken<>AS_SEPARATOR then
|
|
|
+ Consume(AS_SEPARATOR);
|
|
|
end;
|
|
|
-*)
|
|
|
-
|
|
|
-const
|
|
|
- asmmode_x86_64_intel_info : tasmmodeinfo =
|
|
|
- (
|
|
|
- id : asmmode_x86_64_intel;
|
|
|
- idtxt : 'INTEL';
|
|
|
- casmreader : tx8664intreader;
|
|
|
- );
|
|
|
+
|
|
|
+ const
|
|
|
+ asmmode_x86_64_intel_info : tasmmodeinfo =
|
|
|
+ (
|
|
|
+ id : asmmode_x86_64_intel;
|
|
|
+ idtxt : 'INTEL';
|
|
|
+ casmreader : tx8664intreader;
|
|
|
+ );
|
|
|
|
|
|
initialization
|
|
|
RegisterAsmMode(asmmode_x86_64_intel_info);
|