nx64cal.pas 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. {
  2. Copyright (c) 2002 by Florian Klaempfl
  3. Implements the x86-64 specific part of call nodes
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit nx64cal;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. symdef,
  22. ncal,nx86cal;
  23. type
  24. tx8664callnode = class(tx86callnode)
  25. protected
  26. procedure gen_syscall_para(para: tcallparanode); override;
  27. procedure extra_call_code;override;
  28. procedure set_result_location(realresdef: tstoreddef);override;
  29. public
  30. procedure do_syscall;override;
  31. end;
  32. implementation
  33. uses
  34. globtype,
  35. systems,verbose,cutils,
  36. cpubase,cgbase,cgutils,cgobj,
  37. symsym,symcpu,nld,
  38. aasmtai,aasmdata,aasmcpu;
  39. { uses
  40. globtype,systems,
  41. cutils,verbose,globals,
  42. cgbase,cgutils,
  43. cpubase,paramgr,
  44. aasmtai,aasmdata,aasmcpu,
  45. nbas,nmem,nld,ncnv,
  46. symdef,symsym,symcpu,
  47. cga,cgobj,cpuinfo;}
  48. procedure tx8664callnode.do_syscall;
  49. var
  50. tmpref: treference;
  51. begin
  52. case target_info.system of
  53. system_x86_64_aros:
  54. begin
  55. // one syscall convention for AROS
  56. current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall')));
  57. reference_reset(tmpref,sizeof(pint));
  58. tmpref.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(tcpuprocdef(procdefinition).libsym).mangledname);
  59. cg.getcpuregister(current_asmdata.CurrAsmList,NR_RAX);
  60. cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_RAX);
  61. reference_reset_base(tmpref,NR_RAX,-tprocdef(procdefinition).extnumber,sizeof(pint));
  62. cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_RAX);
  63. cg.a_call_reg(current_asmdata.CurrAsmList,NR_RAX);
  64. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_RAX);
  65. end;
  66. else
  67. internalerror(2015062801);
  68. end;
  69. end;
  70. procedure tx8664callnode.gen_syscall_para(para: tcallparanode);
  71. begin
  72. { lib parameter has no special type but proccalloptions must be a syscall }
  73. para.left:=cloadnode.create(tcpuprocdef(procdefinition).libsym,tcpuprocdef(procdefinition).libsym.owner);
  74. end;
  75. procedure tx8664callnode.extra_call_code;
  76. var
  77. mmregs : aint;
  78. begin
  79. { x86_64 requires %al to contain the no. SSE regs passed }
  80. if (cnf_uses_varargs in callnodeflags) and (target_info.system<>system_x86_64_win64) then
  81. begin
  82. if assigned(varargsparas) then
  83. mmregs:=varargsparas.mmregsused
  84. else
  85. mmregs:=0;
  86. current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_MOV,S_Q,mmregs,NR_RAX))
  87. end;
  88. end;
  89. procedure tx8664callnode.set_result_location(realresdef: tstoreddef);
  90. begin
  91. { avoid useless "movq %xmm0,%rax" and "movq %rax,%xmm0" instructions
  92. (which moreover for some reason are not supported by the Darwin
  93. x86-64 assembler) }
  94. if assigned(retloc.location) and
  95. not assigned(retloc.location^.next) and
  96. (retloc.location^.loc in [LOC_MMREGISTER,LOC_CMMREGISTER]) then
  97. begin
  98. location_reset(location,LOC_MMREGISTER,retloc.location^.size);
  99. location.register:=cg.getmmregister(current_asmdata.CurrAsmList,retloc.location^.size);
  100. end
  101. else
  102. inherited
  103. end;
  104. begin
  105. ccallnode:=tx8664callnode;
  106. end.