added checks and crossfiles

This commit is contained in:
Félix 2024-10-13 01:20:10 -04:00
parent 53e4fae669
commit b7883cd0aa
2 changed files with 92 additions and 86 deletions

View file

@ -1,37 +1,41 @@
const vscode = require('vscode'); const vscode = require('vscode');
const axios = require('axios'); const axios = require('axios');
const cheerio = require('cheerio'); const cheerio = require('cheerio');
const list = require('./mnemonics.js');
function activate(context) { function activate(context) {
// Existing hover provider // Hover provider for mnemonics
const hoverProvider = vscode.languages.registerHoverProvider('x86asm', { const hoverProvider = vscode.languages.registerHoverProvider('x86asm', {
async provideHover(document, position, token) { async provideHover(document, position, token) {
const range = document.getWordRangeAtPosition(position, /\b[a-zA-Z0-9_]+\b/); const range = document.getWordRangeAtPosition(position, /\b[a-zA-Z0-9_]+\b/);
const word = document.getText(range); const word = document.getText(range);
if (word) { if (word) {
const instructionInfo = await fetchInstructionInfo(word.toLowerCase()); // Check if the word is a valid mnemonic
if (instructionInfo) { if (list.x86x64Mnemonics.includes(word.toUpperCase())) {
return new vscode.Hover(instructionInfo); const instructionInfo = await fetchInstructionInfo(word.toLowerCase());
} else if (isLabel(document, word)) { if (instructionInfo) {
return new vscode.Hover(`Label: ${word}`); return new vscode.Hover(instructionInfo);
} }
} else {
return new vscode.Hover(`Unrecognized mnemonic: ${word}`);
}
} }
return undefined; return undefined;
} }
}); });
// New definition provider (Ctrl+Click to jump) // Definition provider (Ctrl+Click to jump)
const definitionProvider = vscode.languages.registerDefinitionProvider('x86asm', { const definitionProvider = vscode.languages.registerDefinitionProvider('x86asm', {
provideDefinition(document, position, token) { async provideDefinition(document, position, token) {
const range = document.getWordRangeAtPosition(position); const range = document.getWordRangeAtPosition(position);
if (!range) { if (!range) {
return; return;
} }
const word = document.getText(range); 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) { async function findDefinition(word) {
const text = document.getText(); // Get all x86 assembly files in the workspace
const lines = text.split('\n'); const files = await vscode.workspace.findFiles('**/*.s', '**/node_modules/**');
// Look for .def directive for (const file of files) {
const defRegex = new RegExp(`\\.def\\s+${word}\\s*;`, 'i'); const document = await vscode.workspace.openTextDocument(file);
for (let i = 0; i < lines.length; i++) { const text = document.getText();
if (defRegex.test(lines[i])) { const lines = text.split('\n');
return new vscode.Location(document.uri, new vscode.Position(i, 0));
}
}
// Look for label // Check for definitions in each file
const labelRegex = new RegExp(`^${word}:`, 'i'); const location = searchForDefinition(lines, word, document);
for (let i = 0; i < lines.length; i++) { if (location) {
if (labelRegex.test(lines[i])) { return location;
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));
} }
} }
@ -156,11 +100,18 @@ function findDefinition(document, word) {
return undefined; return undefined;
} }
// Helper function to check if a word is a label in the document function searchForDefinition(lines, word, document) {
function isLabel(document, word) { const externRegex = new RegExp(`^extern\\s+${word}\\s*`, 'i');
const text = document.getText(); const globalRegex = new RegExp(`^global\\s+${word}\\s*`, 'i');
const labelRegex = new RegExp(`^${word}:`, '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() {} function deactivate() {}
@ -168,4 +119,4 @@ function deactivate() {}
module.exports = { module.exports = {
activate, activate,
deactivate deactivate
}; };

55
src/mnemonics.js Normal file
View file

@ -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
};