• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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