n386inl.pas 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Generate i386 inline 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 n386inl;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. node,nx86inl;
  22. type
  23. ti386inlinenode = class(tx86inlinenode)
  24. public
  25. function first_sar: tnode; override;
  26. procedure second_rox_sar; override;
  27. end;
  28. implementation
  29. uses
  30. globtype,globals,
  31. defutil,
  32. aasmbase,aasmdata,
  33. cgbase,pass_2,
  34. cpuinfo,cpubase,
  35. cga,cgutils,cgx86,cgobj,hlcgobj,
  36. ninl,ncon,ncal;
  37. function ti386inlinenode.first_sar: tnode;
  38. begin
  39. if is_64bitint(resultdef) and (
  40. (inlinenumber=in_sar_x) or (
  41. (inlinenumber=in_sar_x_y) and
  42. (tcallparanode(left).left.nodetype=ordconstn)
  43. )) then
  44. begin
  45. result:=nil;
  46. expectloc:=LOC_REGISTER;
  47. end
  48. else
  49. result:=inherited first_sar;
  50. end;
  51. procedure ti386inlinenode.second_rox_sar;
  52. var
  53. op1: tnode;
  54. hreg64hi,hreg64lo: tregister;
  55. v: aint;
  56. begin
  57. if is_64bitint(resultdef) and (
  58. (inlinenumber=in_sar_x) or (
  59. (inlinenumber=in_sar_x_y) and
  60. (tcallparanode(left).left.nodetype=ordconstn)
  61. )) then
  62. begin
  63. { x sar constant }
  64. if (left.nodetype=callparan) and
  65. assigned(tcallparanode(left).right) then
  66. begin
  67. op1:=tcallparanode(tcallparanode(left).right).left;
  68. secondpass(tcallparanode(left).left);
  69. v:=Tordconstnode(tcallparanode(left).left).value.svalue and 63;
  70. end
  71. else
  72. begin
  73. op1:=left;
  74. v:=1;
  75. end;
  76. secondpass(op1);
  77. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  78. { load left operator in a register }
  79. hlcg.location_force_reg(current_asmdata.CurrAsmList,op1.location,op1.resultdef,resultdef,false);
  80. hreg64hi:=op1.location.register64.reghi;
  81. hreg64lo:=op1.location.register64.reglo;
  82. if (v=63) then
  83. begin
  84. emit_const_reg(A_SAR,S_L,31,hreg64hi);
  85. cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,hreg64hi,hreg64lo);
  86. end
  87. else if (v>31) then
  88. begin
  89. cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,hreg64hi,hreg64lo);
  90. emit_const_reg(A_SAR,S_L,31,hreg64hi);
  91. emit_const_reg(A_SAR,S_L,v and 31,hreg64lo);
  92. end
  93. else
  94. begin
  95. emit_const_reg_reg(A_SHRD,S_L,v and 31,hreg64hi,hreg64lo);
  96. emit_const_reg(A_SAR,S_L,v and 31,hreg64hi);
  97. end;
  98. location.register64.reghi:=hreg64hi;
  99. location.register64.reglo:=hreg64lo;
  100. end
  101. else
  102. inherited second_rox_sar;
  103. end;
  104. begin
  105. cinlinenode:=ti386inlinenode;
  106. end.