codegen-x86-test.js (3016B)
1 // Scaffolding for testing x86 Ion code generation patterns . See 2 // codegen-x64-test.js in this directory for more information. 3 4 load(libdir + "codegen-test-common.js"); 5 6 // Note that Zydis disassembles x86 absolute addresses as relative, so 7 // the binary encoding and the text encoding may not correspond precisely. 8 9 // Absolute address (disp32) following the instruction mnemonic. 10 var ABS = `0x${HEXES}`; 11 12 // End of prologue. The move from esi to rbp is writing the callee's wasm 13 // instance into the frame for debug checks -- see WasmFrame.h. The mov to eax 14 // is debug code, inserted by the register allocator to clobber eax before a 15 // move group. But it is only present if there is a move group there. 16 // 17 // -0x21524111 is 0xDEADBEEF. 18 var x86_prefix = ` 19 mov %esp, %ebp( 20 movl %esi, 0x08\\(%rbp\\))?( 21 mov \\$-0x21524111, %eax)? 22 ` 23 24 // `.bp` because zydis chooses 'rbp' even on 32-bit systems 25 var x86_loadarg0 = ` 26 movdqux 0x${HEXES}\\(%.bp\\), %xmm0 27 `; 28 29 // Start of epilogue. `.bp` for the same reason as above. 30 var x86_suffix = `pop %.bp`; 31 32 // v128 OP literal -> v128 33 // inputs: [[complete-opname, rhs-literal, expected-pattern], ...] 34 function codegenTestX86_v128xLITERAL_v128(inputs, options = {}) { 35 for ( let [op, literal, expected] of inputs ) { 36 codegenTestX86_adhoc(wrap(options, ` 37 (func (export "f") (param v128) (result v128) 38 (${op} (local.get 0) ${literal}))`), 39 'f', 40 x86_loadarg0 + expected, 41 options) 42 } 43 } 44 45 // For when nothing else applies: `module_text` is the complete source text of 46 // the module, `export_name` is the name of the function to be tested, 47 // `expected` is the non-preprocessed pattern, and options is an options bag, 48 // described above. 49 function codegenTestX86_adhoc(module_text, export_name, expected, options = {}) { 50 assertEq(hasDisassembler(), true); 51 52 let ins = wasmEvalText(module_text); 53 let output = wasmDis(ins.exports[export_name], {tier:"ion", asString:true}); 54 55 const expected_initial = expected; 56 if (!options.no_prefix) 57 expected = x86_prefix + '\n' + expected; 58 if (!options.no_suffix) 59 expected = expected + '\n' + x86_suffix; 60 expected = fixlines(expected); 61 62 const output_simple = stripencoding(output, `(?:${HEX}{2} )*`); 63 const output_matches_expected = output_simple.match(new RegExp(expected)) != null; 64 if (!output_matches_expected) { 65 print("---- codegen-x86-test.js: TEST FAILED ----"); 66 } 67 if (options.log && output_matches_expected) { 68 print("---- codegen-x86-test.js: TEST PASSED ----"); 69 } 70 if (options.log || !output_matches_expected) { 71 print("---- module text"); 72 print(module_text); 73 print("---- actual"); 74 print(output); 75 print("---- expected (initial)"); 76 print(expected_initial); 77 print("---- expected (as used)"); 78 print(expected); 79 print("----"); 80 } 81 82 assertEq(output_matches_expected, true); 83 }