From b7883cd0aaea3e8e64aff69f2cbb3732817e6924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix?= <142559040+kapitche@users.noreply.github.com> Date: Sun, 13 Oct 2024 01:20:10 -0400 Subject: [PATCH] added checks and crossfiles --- src/extension.js | 123 ++++++++++++++--------------------------------- src/mnemonics.js | 55 +++++++++++++++++++++ 2 files changed, 92 insertions(+), 86 deletions(-) create mode 100644 src/mnemonics.js diff --git a/src/extension.js b/src/extension.js index 994da88..0e19564 100644 --- a/src/extension.js +++ b/src/extension.js @@ -1,37 +1,41 @@ const vscode = require('vscode'); const axios = require('axios'); const cheerio = require('cheerio'); +const list = require('./mnemonics.js'); function activate(context) { - // Existing hover provider + // Hover provider for mnemonics const hoverProvider = vscode.languages.registerHoverProvider('x86asm', { async provideHover(document, position, token) { const range = document.getWordRangeAtPosition(position, /\b[a-zA-Z0-9_]+\b/); const word = document.getText(range); if (word) { - const instructionInfo = await fetchInstructionInfo(word.toLowerCase()); - if (instructionInfo) { - return new vscode.Hover(instructionInfo); - } else if (isLabel(document, word)) { - return new vscode.Hover(`Label: ${word}`); - } + // Check if the word is a valid mnemonic + if (list.x86x64Mnemonics.includes(word.toUpperCase())) { + const instructionInfo = await fetchInstructionInfo(word.toLowerCase()); + if (instructionInfo) { + return new vscode.Hover(instructionInfo); + } + } else { + return new vscode.Hover(`Unrecognized mnemonic: ${word}`); + } } return undefined; } }); - // New definition provider (Ctrl+Click to jump) + // Definition provider (Ctrl+Click to jump) const definitionProvider = vscode.languages.registerDefinitionProvider('x86asm', { - provideDefinition(document, position, token) { + async provideDefinition(document, position, token) { const range = document.getWordRangeAtPosition(position); if (!range) { return; } const word = document.getText(range); - return findDefinition(document, word); + return await findDefinition(word); } }); @@ -76,79 +80,19 @@ async function fetchInstructionInfo(instruction) { } } -function findDefinition(document, word) { - const text = document.getText(); - const lines = text.split('\n'); +async function findDefinition(word) { + // Get all x86 assembly files in the workspace + const files = await vscode.workspace.findFiles('**/*.s', '**/node_modules/**'); - // Look for .def directive - const defRegex = new RegExp(`\\.def\\s+${word}\\s*;`, 'i'); - for (let i = 0; i < lines.length; i++) { - if (defRegex.test(lines[i])) { - return new vscode.Location(document.uri, new vscode.Position(i, 0)); - } - } + for (const file of files) { + const document = await vscode.workspace.openTextDocument(file); + const text = document.getText(); + const lines = text.split('\n'); - // Look for label - const labelRegex = new RegExp(`^${word}:`, 'i'); - for (let i = 0; i < lines.length; i++) { - if (labelRegex.test(lines[i])) { - return new vscode.Location(document.uri, new vscode.Position(i, 0)); - } - } - - // Look for extern declarations - const externRegex = new RegExp(`^extern\\s+${word}\\s*`, 'i'); - for (let i = 0; i < lines.length; i++) { - if (externRegex.test(lines[i])) { - return new vscode.Location(document.uri, new vscode.Position(i, 0)); - } - } - - // Look for global declarations - const globalRegex = new RegExp(`^global\\s+${word}\\s*`, 'i'); - for (let i = 0; i < lines.length; i++) { - if (globalRegex.test(lines[i])) { - return new vscode.Location(document.uri, new vscode.Position(i, 0)); - } - } - - // Look for struct definitions - const structRegex = new RegExp(`^\\s*struc\\s+${word}\\s*`, 'i'); - for (let i = 0; i < lines.length; i++) { - if (structRegex.test(lines[i])) { - return new vscode.Location(document.uri, new vscode.Position(i, 0)); - } - } - - // Look for section declarations - const sectionRegex = new RegExp(`^section\\s+${word}\\s*`, 'i'); - for (let i = 0; i < lines.length; i++) { - if (sectionRegex.test(lines[i])) { - return new vscode.Location(document.uri, new vscode.Position(i, 0)); - } - } - - // Look for macro definitions - const macroRegex = new RegExp(`^\\s*%define\\s+${word}\\s*`, 'i'); - for (let i = 0; i < lines.length; i++) { - if (macroRegex.test(lines[i])) { - return new vscode.Location(document.uri, new vscode.Position(i, 0)); - } - } - - // Look for equates - const equateRegex = new RegExp(`\\bequ\\s+${word}\\s*`, 'i'); - for (let i = 0; i < lines.length; i++) { - if (equateRegex.test(lines[i])) { - return new vscode.Location(document.uri, new vscode.Position(i, 0)); - } - } - - // Look for data declarations (db, dw, dd) - const dataRegex = new RegExp(`\\b${word}\\s+`, 'i'); - for (let i = 0; i < lines.length; i++) { - if (dataRegex.test(lines[i])) { - return new vscode.Location(document.uri, new vscode.Position(i, 0)); + // Check for definitions in each file + const location = searchForDefinition(lines, word, document); + if (location) { + return location; } } @@ -156,11 +100,18 @@ function findDefinition(document, word) { return undefined; } -// Helper function to check if a word is a label in the document -function isLabel(document, word) { - const text = document.getText(); +function searchForDefinition(lines, word, document) { + const externRegex = new RegExp(`^extern\\s+${word}\\s*`, 'i'); + const globalRegex = new RegExp(`^global\\s+${word}\\s*`, 'i'); const labelRegex = new RegExp(`^${word}:`, 'i'); - return labelRegex.test(text); + + for (let i = 0; i < lines.length; i++) { + if (externRegex.test(lines[i]) || globalRegex.test(lines[i]) || labelRegex.test(lines[i])) { + return new vscode.Location(document.uri, new vscode.Position(i, 0)); + } + } + + return undefined; // If no match is found } function deactivate() {} @@ -168,4 +119,4 @@ function deactivate() {} module.exports = { activate, deactivate -}; \ No newline at end of file +}; diff --git a/src/mnemonics.js b/src/mnemonics.js new file mode 100644 index 0000000..052bb97 --- /dev/null +++ b/src/mnemonics.js @@ -0,0 +1,55 @@ +const x86x64Mnemonics = [ + // Data Transfer + "MOV", "LEA", "PUSH", "POP", "XCHG", "MOVSX", "MOVZX", "CVTSI2SD", "CVTSD2SI", + "MOVD", "MOVQ", "MOVSS", "MOVSD", "MOVAPD", "MOVDQA", "MOVDQU", + "MOVNTI", "MOVNTQ", "MOVNTDQ", "MOVNTDQA", "MOVNTQ", "MOVNTDQ", + // Arithmetic and Logical + "ADD", "SUB", "MUL", "DIV", "INC", "DEC", "AND", "OR", "XOR", "NOT", "SHL", "SHR", + "SAL", "SAR", "SHRD", "SHLD", "IMUL", "IDIV", "IDIVQ", "MULSD", "DIVSD", + "ADDPD", "SUBPD", "MULPD", "DIVPD", "ANDPD", "ORPD", "XORPD", + "ADDPS", "SUBPS", "MULPS", "DIVPS", "ANDPS", "ORPS", "XORPS", + // Control Flow + "JMP", "Jcc", "CALL", "RET", "LOOP", "JNZ", "JZ", "JE", "JNE", "JL", "JLE", + "JG", "JGE", "JB", "JBE", "JA", "JAE", "LOOPNE", "LOOPE", + "LOOPNZ", "LOOPZ", "CMOVcc", "SETcc", + // Other + "CMP", "TEST", "NEG", "NOT", "CLD", "STD", "CWD", "CDQ", "CQO", + "LEA", "LES", "LDS", "LSS", "LFS", "LGS", + "LES", "LDS", "LSS", "LFS", "LGS", + "REP", "REPE", "REPNE", "REPZ", "REPNZ", + "BSF", "BSR", "BT", "BTC", "BTR", "BTS", "LEAVE", + // Floating-Point + "FADD", "FSUB", "FMUL", "FDIV", "FCHS", "FABS", "FCOM", "FCOMP", "FCOMPP", + "FADD", "FSUB", "FMUL", "FDIV", "FCHS", "FABS", "FCOM", "FCOMP", "FCOMPP", + "FST", "FSTPN", "FSTP", "FLD", "FLD1", "FLDPI", "FLDL2T", "FLDL2E", + "FLDCW", "FSTCW", + "FCOMI", "FCOMIP", "FUCOMI", "FUCOMIP", + // SIMD + "MOVDQA", "MOVDQU", "PSHUFD", "PSHUFLW", "PSHUFLH", "PSLLD", "PSLLQ", "PSLLW", + "PSRAD", "PSRAQ", "PSRAW", "PADDW", "PADDQ", "PADDUSB", "PADDUSW", + "PSUBW", "PSUBQ", "PSUBUSB", "PSUBUSW", + "PMADDWD", "PMULHW", "PMULLW", + "PMAXSW", "PMAXUW", "PMINSW", "PMINUW", + // AVX Instructions + "VMOVD", "VMOVQ", "VMOVSS", "VMOVSD", "VMOVAPD", "VMOVDQA", "VMOVDQU", + "VADDPD", "VADDPS", "VADDL", "VADDL2", "VADDL3", "VADDL4", + "VSUBPD", "VSUBPS", "VSUBL", "VSUBL2", "VSUBL3", "VSUBL4", + "VMULPD", "VMULPS", "VMULL", "VMULL2", "VMULL3", "VMULL4", + "VDIVPD", "VDIVPS", "VDIVL", "VDIVL2", "VDIVL3", "VDIVL4", + "VANDPD", "VANDPS", "VANDL", "VANDL2", "VANDL3", "VANDL4", + "VORPD", "VORPS", "VORL", "VORL2", "VORL3", "VORL4", + "VXORPD", "VXORPS", "VXORL", "VXORL2", "VXORL3", "VXORL4", + // AVX-512 Instructions + "VPMOVD", "VPMOVQ", "VPMOVSS", "VPMOVSD", "VPMOVAPD", "VPMOVDQA", "VPMOVDQU", + "VPADDPD", "VPADDPS", "VPADDL", "VPADDL2", "VPADDL3", "VPADDL4", + "VPSUBPD", "VPSUBPS", "VPSUBL", "VPSUBL2", "VPSUBL3", "VPSUBL4", + "VPMULPD", "VPMULPS", "VPMULL", "VPMULL2", "VPMULL3", "VPMULL4", + "VPDIVPD", "VPDIVPS", "VPDIVL", "VPDIVL2", "VPDIVL3", "VPDIVL4", + "VPANDPD", "VPANDPS", "VPANDL", "VPANDL2", "VPANDL3", "VPANDL4", + "VPORPD", "VPORPS", "VPORL", "VPORL2", "VPORL3", "VPORL4", + "VPXORPD", "VPXORPS", "VPXORL", "VPXORL2", "VPXORL3", "VPXORL4", + ]; + + module.exports = { + x86x64Mnemonics + }; \ No newline at end of file