{ Copyright (c) 2024 by J. Gareth "Kit" Moreton This unit implements the x86-specific assembly node This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. **************************************************************************** } unit nx86bas; {$i fpcdefs.inc} interface uses nbas, ncgbas, aasmtai; type Tx86AsmNode = class(TCGAsmNode) {$ifdef DEBUG_NODE_XML} procedure XMLPrintNodeData(var T: Text); override; protected function XMLFormatOp(const Oper: POper): string; override; procedure XMLProcessInstruction(var T: Text; p: tai); override; {$endif DEBUG_NODE_XML} end; implementation {$ifdef DEBUG_NODE_XML} uses cutils, cgutils, cgbase, cpubase, itcpugas, aasmcpu, verbose; {$endif DEBUG_NODE_XML} {$ifdef DEBUG_NODE_XML} function Tx86AsmNode.XMLFormatOp(const Oper: POper): string; begin case Oper^.typ of top_const: begin case Oper^.val of -15..15: Result := '$' + tostr(Oper^.val); $10..$FF: Result := '$0x' + hexstr(Oper^.val, 2); $100..$FFFF: Result := '$0x' + hexstr(Oper^.val, 4); {$ifdef CPU64} $10000..$FFFFFFFF: Result := '$0x' + hexstr(Oper^.val, 8); else Result := '$0x' + hexstr(Oper^.val, 16); {$else CPU64} else Result := '$0x' + hexstr(Oper^.val, 8); {$endif CPU64} end; end; top_ref: with Oper^.ref^ do begin if segment <> NR_NO then Result := gas_regname(segment) + ':' else Result := ''; if Assigned(symbol) then begin Result := Result + symbol.Name; if offset > 0 then Result := Result + '+'; end; if offset <> 0 then Result := Result + tostr(offset) else Result := Result; if (base <> NR_NO) or (index <> NR_NO) then begin Result := Result + '('; if base <> NR_NO then begin Result := Result + gas_regname(base); if index <> NR_NO then Result := Result + ','; end; if index <> NR_NO then Result := Result + gas_regname(index); if scalefactor <> 0 then Result := Result + ',' + tostr(scalefactor) + ')' else Result := Result + ')'; end; end; else Result := inherited XMLFormatOp(Oper); end; end; procedure Tx86AsmNode.XMLProcessInstruction(var T: Text; p: tai); var ThisOp, ThisOper: string; X: Integer; begin if p.typ = ait_instruction then begin ThisOp := gas_op2str[taicpu(p).opcode] + cond2str[taicpu(p).condition]; if gas_needsuffix[taicpu(p).opcode] <> AttSufNONE then ThisOp := ThisOp + gas_opsize2str[taicpu(p).opsize]; { Pad the opcode with spaces so the succeeding operands are aligned } XMLPadString(ThisOp, 7); Write(T, PrintNodeIndention, ' ', ThisOp); { Extra indentation to account for label formatting } for X := 0 to taicpu(p).ops - 1 do begin Write(T, ' '); ThisOper := XMLFormatOp(taicpu(p).oper[X]); if X < taicpu(p).ops - 1 then begin ThisOper := ThisOper + ','; XMLPadString(ThisOper, 7); end; Write(T, ThisOper); end; WriteLn(T); end else inherited XMLProcessInstruction(T, p); end; procedure Tx86AsmNode.XMLPrintNodeData(var T: Text); var hp: tai; begin if not Assigned(p_asm) then Exit; hp := tai(p_asm.First); while Assigned(hp) do begin XMLProcessInstruction(T, hp); hp := tai(hp.Next); end; end; {$endif DEBUG_NODE_XML} initialization casmnode := Tx86AsmNode; end.