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