nx86bas.pas 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. {
  2. Copyright (c) 2024 by J. Gareth "Kit" Moreton
  3. This unit implements the x86-specific assembly node
  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 nx86bas;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. nbas, ncgbas, aasmtai;
  22. type
  23. Tx86AsmNode = class(TCGAsmNode)
  24. {$ifdef DEBUG_NODE_XML}
  25. procedure XMLPrintNodeData(var T: Text); override;
  26. protected
  27. function XMLFormatOp(const Oper: POper): string; override;
  28. procedure XMLProcessInstruction(var T: Text; p: tai); override;
  29. {$endif DEBUG_NODE_XML}
  30. end;
  31. implementation
  32. {$ifdef DEBUG_NODE_XML}
  33. uses
  34. cutils,
  35. cgutils,
  36. cgbase,
  37. cpubase,
  38. itcpugas,
  39. aasmcpu,
  40. verbose;
  41. {$endif DEBUG_NODE_XML}
  42. {$ifdef DEBUG_NODE_XML}
  43. function Tx86AsmNode.XMLFormatOp(const Oper: POper): string;
  44. begin
  45. case Oper^.typ of
  46. top_const:
  47. begin
  48. case Oper^.val of
  49. -15..15:
  50. Result := '$' + tostr(Oper^.val);
  51. $10..$FF:
  52. Result := '$0x' + hexstr(Oper^.val, 2);
  53. $100..$FFFF:
  54. Result := '$0x' + hexstr(Oper^.val, 4);
  55. {$ifdef CPU64}
  56. $10000..$FFFFFFFF:
  57. Result := '$0x' + hexstr(Oper^.val, 8);
  58. else
  59. Result := '$0x' + hexstr(Oper^.val, 16);
  60. {$else CPU64}
  61. else
  62. Result := '$0x' + hexstr(Oper^.val, 8);
  63. {$endif CPU64}
  64. end;
  65. end;
  66. top_ref:
  67. with Oper^.ref^ do
  68. begin
  69. if segment <> NR_NO then
  70. Result := gas_regname(segment) + ':'
  71. else
  72. Result := '';
  73. if Assigned(symbol) then
  74. begin
  75. Result := Result + symbol.Name;
  76. if offset > 0 then
  77. Result := Result + '+';
  78. end;
  79. if offset <> 0 then
  80. Result := Result + tostr(offset)
  81. else
  82. Result := Result;
  83. if (base <> NR_NO) or (index <> NR_NO) then
  84. begin
  85. Result := Result + '(';
  86. if base <> NR_NO then
  87. begin
  88. Result := Result + gas_regname(base);
  89. if index <> NR_NO then
  90. Result := Result + ',';
  91. end;
  92. if index <> NR_NO then
  93. Result := Result + gas_regname(index);
  94. if scalefactor <> 0 then
  95. Result := Result + ',' + tostr(scalefactor) + ')'
  96. else
  97. Result := Result + ')';
  98. end;
  99. end;
  100. else
  101. Result := inherited XMLFormatOp(Oper);
  102. end;
  103. end;
  104. procedure Tx86AsmNode.XMLProcessInstruction(var T: Text; p: tai);
  105. var
  106. ThisOp, ThisOper: string;
  107. X: Integer;
  108. begin
  109. if p.typ = ait_instruction then
  110. begin
  111. ThisOp := gas_op2str[taicpu(p).opcode] + cond2str[taicpu(p).condition];
  112. if gas_needsuffix[taicpu(p).opcode] <> AttSufNONE then
  113. ThisOp := ThisOp + gas_opsize2str[taicpu(p).opsize];
  114. { Pad the opcode with spaces so the succeeding operands are aligned }
  115. XMLPadString(ThisOp, 7);
  116. Write(T, PrintNodeIndention, ' ', ThisOp); { Extra indentation to account for label formatting }
  117. for X := 0 to taicpu(p).ops - 1 do
  118. begin
  119. Write(T, ' ');
  120. ThisOper := XMLFormatOp(taicpu(p).oper[X]);
  121. if X < taicpu(p).ops - 1 then
  122. begin
  123. ThisOper := ThisOper + ',';
  124. XMLPadString(ThisOper, 7);
  125. end;
  126. Write(T, ThisOper);
  127. end;
  128. WriteLn(T);
  129. end
  130. else
  131. inherited XMLProcessInstruction(T, p);
  132. end;
  133. procedure Tx86AsmNode.XMLPrintNodeData(var T: Text);
  134. var
  135. hp: tai;
  136. begin
  137. if not Assigned(p_asm) then
  138. Exit;
  139. hp := tai(p_asm.First);
  140. while Assigned(hp) do
  141. begin
  142. XMLProcessInstruction(T, hp);
  143. hp := tai(hp.Next);
  144. end;
  145. end;
  146. {$endif DEBUG_NODE_XML}
  147. initialization
  148. casmnode := Tx86AsmNode;
  149. end.