1// Copyright 2019 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import { assert } from "chai"; 16import Lexer from "./lexer"; 17import Parser from "./parser"; 18import grammar from "./spirv.data.js"; 19import Assembler from "./assembler"; 20 21describe("assembler", () => { 22 it("generates SPIR-V magic number", () => { 23 let input = `; SPIR-V 24; Version: 1.0 25; Generator: Khronos Glslang Reference Front End; 7 26; Bound: 6 27; Schema: 0 28 OpCapability Shader 29 %1 = OpExtInstImport "GLSL.std.450" 30 OpMemoryModel Logical GLSL450 31 OpEntryPoint Fragment %main "main" 32 OpExecutionMode %main OriginUpperLeft 33 OpSource GLSL 440 34 OpName %main "main" 35 %void = OpTypeVoid 36 %3 = OpTypeFunction %void 37 %main = OpFunction %void None %3 38 %5 = OpLabel 39 OpReturn 40 OpFunctionEnd`; 41 let l = new Lexer(input); 42 let p = new Parser(grammar, l); 43 44 let ast = p.parse(); 45 assert.exists(ast, p.error); 46 47 let a = new Assembler(ast); 48 let res = a.assemble(); 49 assert.equal(res[0], 0x07230203); 50 }); 51 52 it("assembles enumerant params", () => { 53 let input = "OpExecutionMode %main LocalSize 2 3 4"; 54 55 let l = new Lexer(input); 56 let p = new Parser(grammar, l); 57 58 let ast = p.parse(); 59 assert.exists(ast, p.error); 60 61 let a = new Assembler(ast); 62 let res = a.assemble(); 63 64 assert.lengthOf(res, 11); 65 assert.equal(res[5], (6 /* word count */ << 16) | 16 /* opcode */); 66 assert.equal(res[6], 1 /* %main */); 67 assert.equal(res[7], 17 /* LocalSize */); 68 assert.equal(res[8], 2); 69 assert.equal(res[9], 3); 70 assert.equal(res[10], 4); 71 }); 72 73 it("assembles float 32 values", () => { 74 let input = `%float = OpTypeFloat 32 75 %float1 = OpConstant %float 0.400000006`; 76 let l = new Lexer(input); 77 let p = new Parser(grammar, l); 78 79 let ast = p.parse(); 80 assert.exists(ast, p.error); 81 82 let a = new Assembler(ast); 83 let res = a.assemble(); 84 85 assert.lengthOf(res, 12); 86 assert.equal(res[8], (4 /* word count */ << 16) | 43 /* opcode */); 87 assert.equal(res[9], 1 /* %float */); 88 assert.equal(res[10], 2 /* %float */); 89 assert.equal(res[11], 0x3ecccccd /* 0.400000006 */); 90 }); 91 92 describe("strings", () => { 93 it("assembles 'abcd'", () => { 94 let input = `OpName %mains "abcd"`; 95 let l = new Lexer(input); 96 let p = new Parser(grammar, l); 97 98 let ast = p.parse(); 99 assert.exists(ast, p.error); 100 101 let a = new Assembler(ast); 102 let res = a.assemble(); 103 104 assert.lengthOf(res, 9); 105 assert.equal(res[5], (4 /* word count */ << 16) | 5 /* opcode */); 106 assert.equal(res[6], 1 /* %mains */); 107 assert.equal(res[7], 0x64636261 /* food */); 108 assert.equal(res[8], 0x00000000 /* null byte */); 109 }); 110 111 it("assembles 'abcde'", () => { 112 let input = `OpName %mains "abcde"`; 113 let l = new Lexer(input); 114 let p = new Parser(grammar, l); 115 116 let ast = p.parse(); 117 assert.exists(ast, p.error); 118 119 let a = new Assembler(ast); 120 let res = a.assemble(); 121 122 assert.lengthOf(res, 9); 123 assert.equal(res[5], (4 /* word count */ << 16) | 5 /* opcode */); 124 assert.equal(res[6], 1 /* %mains */); 125 assert.equal(res[7], 0x64636261 /* abcd */); 126 assert.equal(res[8], 0x00000065 /* e */); 127 }); 128 129 it("assembles 'abcdef'", () => { 130 let input = `OpName %mains "abcdef"`; 131 let l = new Lexer(input); 132 let p = new Parser(grammar, l); 133 134 let ast = p.parse(); 135 assert.exists(ast, p.error); 136 137 let a = new Assembler(ast); 138 let res = a.assemble(); 139 140 assert.lengthOf(res, 9); 141 assert.equal(res[5], (4 /* word count */ << 16) | 5 /* opcode */); 142 assert.equal(res[6], 1 /* %mains */); 143 assert.equal(res[7], 0x64636261 /* abcd */); 144 assert.equal(res[8], 0x00006665 /* ef */); 145 }); 146 147 it("assembles 'abcdefg'", () => { 148 let input = `OpName %mains "abcdefg"`; 149 let l = new Lexer(input); 150 let p = new Parser(grammar, l); 151 152 let ast = p.parse(); 153 assert.exists(ast, p.error); 154 155 let a = new Assembler(ast); 156 let res = a.assemble(); 157 158 assert.lengthOf(res, 9); 159 assert.equal(res[5], (4 /* word count */ << 16) | 5 /* opcode */); 160 assert.equal(res[6], 1 /* %mains */); 161 assert.equal(res[7], 0x64636261 /* abcd */); 162 assert.equal(res[8], 0x00676665 /* efg */); 163 }); 164 }); 165}); 166