355
|
1 import unittest
|
366
|
2 import os
|
|
3 import io
|
375
|
4 from testemulation import runQemu, has_qemu
|
366
|
5 from testzcc import relpath
|
377
|
6 from ppci.buildfunctions import assemble, c3compile, link
|
355
|
7
|
398
|
8 mod_io_src = """
|
|
9 module io;
|
|
10 import arch;
|
|
11
|
|
12 function void println(string txt)
|
|
13 {
|
|
14 print(txt);
|
|
15 arch.putc(10); // Newline!
|
|
16 }
|
|
17
|
|
18 function void print(string txt)
|
|
19 {
|
|
20 var int i;
|
|
21 i = 0;
|
|
22
|
|
23 while (i < txt->len)
|
|
24 {
|
|
25 arch.putc(cast<int>(txt->txt[i]));
|
|
26 i = i + 1;
|
|
27 }
|
|
28 }
|
|
29
|
|
30 // Print integer in hexadecimal notation:
|
|
31 function void print_int(int i)
|
|
32 {
|
|
33 print("0x");
|
|
34
|
|
35 // int txt[20];
|
|
36 var int b;
|
|
37 var int c;
|
|
38
|
|
39 for (b=28; b >= 0; b = b - 4)
|
|
40 {
|
|
41 c = (i >> b) & 0xF;
|
|
42 if (c < 10)
|
|
43 {
|
|
44 arch.putc( 48 + c );
|
|
45 }
|
|
46 else
|
|
47 {
|
|
48 arch.putc( 65 - 10 + c );
|
|
49 }
|
|
50 }
|
|
51
|
|
52 arch.putc(10); // Newline!
|
|
53 }
|
|
54
|
|
55 function void print2(string label, int value)
|
|
56 {
|
|
57 print(label);
|
|
58 print_int(value);
|
|
59 }
|
366
|
60 """
|
355
|
61
|
383
|
62
|
358
|
63 class Samples:
|
355
|
64 def testPrint(self):
|
|
65 snippet = """
|
366
|
66 module sample;
|
355
|
67 import io;
|
|
68 function void start()
|
|
69 {
|
|
70 io.print("Hello world");
|
|
71 }
|
|
72 """
|
|
73 self.do(snippet, "Hello world")
|
|
74
|
|
75 def testForLoopPrint(self):
|
|
76 snippet = """
|
366
|
77 module sample;
|
355
|
78 import io;
|
|
79 function void start()
|
|
80 {
|
|
81 var int i;
|
366
|
82 for (i=0; i<10; i = i + 1)
|
355
|
83 {
|
362
|
84 io.print2("A = ", i);
|
355
|
85 }
|
|
86 }
|
|
87 """
|
362
|
88 res = "".join("A = 0x{0:08X}\n".format(a) for a in range(10))
|
|
89 self.do(snippet, res)
|
355
|
90
|
374
|
91 def testIfStatement(self):
|
|
92 snippet = """
|
|
93 module sample;
|
|
94 import io;
|
|
95 function void start()
|
|
96 {
|
|
97 var int i;
|
|
98 i = 13;
|
|
99 if (i*7 < 100)
|
|
100 {
|
|
101 io.print("Wow");
|
|
102 }
|
|
103 else
|
|
104 {
|
|
105 io.print("Outch");
|
|
106 }
|
|
107 }
|
|
108 """
|
|
109 res = "Wow"
|
|
110 self.do(snippet, res)
|
|
111
|
372
|
112 def testParameterPassing4(self):
|
|
113 snippet = """
|
|
114 module sample;
|
|
115 import io;
|
|
116 function void dump(int a, int b, int c, int d)
|
|
117 {
|
|
118 io.print2("a=", a);
|
|
119 io.print2("b=", b);
|
|
120 io.print2("c=", c);
|
|
121 io.print2("d=", d);
|
|
122 }
|
|
123 function void start()
|
|
124 {
|
|
125 dump(4,55,66,0x1337);
|
|
126 }
|
|
127 """
|
|
128 res = "a=0x{0:08X}\n".format(4)
|
|
129 res += "b=0x{0:08X}\n".format(55)
|
|
130 res += "c=0x{0:08X}\n".format(66)
|
|
131 res += "d=0x{0:08X}\n".format(0x1337)
|
|
132 self.do(snippet, res)
|
|
133
|
366
|
134 def testGlobalVariable(self):
|
364
|
135 snippet = """
|
366
|
136 module sample;
|
364
|
137 import io;
|
|
138 var int G;
|
|
139 function void do1()
|
|
140 {
|
|
141 G = G + 1;
|
|
142 io.print2("G=", G);
|
|
143 }
|
|
144 function void do5()
|
|
145 {
|
|
146 G = G + 5;
|
|
147 io.print2("G=", G);
|
|
148 }
|
|
149 function void start()
|
|
150 {
|
|
151 G = 0;
|
|
152 do1();
|
|
153 do1();
|
366
|
154 do5();
|
364
|
155 do1();
|
366
|
156 do5();
|
364
|
157 }
|
|
158 """
|
398
|
159 res = "".join("G=0x{0:08X}\n".format(a) for a in [1, 2, 7, 8, 13])
|
364
|
160 self.do(snippet, res)
|
|
161
|
355
|
162
|
358
|
163 class TestSamplesOnVexpress(unittest.TestCase, Samples):
|
375
|
164 def setUp(self):
|
|
165 if not has_qemu():
|
|
166 self.skipTest('Not running qemu tests')
|
|
167
|
355
|
168 def do(self, src, expected_output):
|
398
|
169 startercode = """
|
|
170 section reset
|
|
171 mov sp, 0x30000 ; setup stack pointer
|
|
172 BL sample_start ; Branch to sample start
|
|
173 local_loop:
|
|
174 B local_loop
|
|
175 """
|
|
176
|
|
177 modarchcode = """
|
|
178 module arch;
|
|
179
|
|
180 function void putc(int c)
|
|
181 {
|
|
182 var int *UART0DR;
|
|
183 UART0DR = cast<int*>(0x10009000); // UART0 DR register
|
|
184 *UART0DR = c;
|
|
185 }
|
|
186
|
|
187 """
|
|
188
|
|
189 arch_mmap = """
|
|
190 MEMORY image LOCATION=0x10000 SIZE=0x10000 {
|
|
191 SECTION(reset)
|
|
192 SECTION(code)
|
|
193 }
|
|
194
|
|
195 MEMORY ram LOCATION=0x20000 SIZE=0x10000 {
|
|
196 SECTION(data)
|
|
197 }
|
|
198 """
|
366
|
199 # Construct binary file from snippet:
|
377
|
200 o1 = assemble(io.StringIO(startercode), 'arm')
|
|
201 o2 = c3compile([
|
366
|
202 relpath('..', 'kernel', 'src', 'io.c3'),
|
381
|
203 io.StringIO(modarchcode),
|
377
|
204 io.StringIO(src)], [], 'arm')
|
385
|
205 o3 = link([o2, o1], io.StringIO(arch_mmap), 'arm')
|
366
|
206
|
385
|
207 img_data = o3.get_image('image')
|
377
|
208 sample_filename = 'testsample.bin'
|
|
209 with open(sample_filename, 'wb') as f:
|
385
|
210 f.write(img_data)
|
377
|
211
|
366
|
212 # Check bin file exists:
|
|
213 self.assertTrue(os.path.isfile(sample_filename))
|
|
214
|
|
215 # Run bin file in emulator:
|
|
216 res = runQemu(sample_filename, machine='vexpress-a9')
|
|
217 os.remove(sample_filename)
|
355
|
218 self.assertEqual(expected_output, res)
|
|
219
|
364
|
220
|
398
|
221 class TestSamplesOnX86(unittest.TestCase, Samples):
|
|
222 def setUp(self):
|
|
223 if not has_qemu():
|
|
224 self.skipTest('Not running qemu tests')
|
|
225 self.skipTest('No x86 target yet')
|
|
226
|
|
227 def do(self, src, expected_output):
|
|
228 # Construct binary file from snippet:
|
|
229 o1 = assemble(io.StringIO(startercode), 'x86')
|
|
230 o2 = c3compile([
|
|
231 relpath('..', 'kernel', 'src', 'io.c3'),
|
|
232 io.StringIO(modarchcode),
|
|
233 io.StringIO(src)], [], 'x86')
|
|
234 o3 = link([o2, o1], io.StringIO(arch_mmap), 'x86')
|
|
235
|
|
236 img_data = o3.get_image('image')
|
|
237 sample_filename = 'testsample.bin'
|
|
238 with open(sample_filename, 'wb') as f:
|
|
239 f.write(img_data)
|
|
240
|
|
241 # Check bin file exists:
|
|
242 self.assertTrue(os.path.isfile(sample_filename))
|
|
243
|
|
244 # Run bin file in emulator:
|
|
245 res = runQemu(sample_filename, machine='vexpress-a9')
|
|
246 os.remove(sample_filename)
|
|
247 self.assertEqual(expected_output, res)
|
|
248
|
383
|
249 # TODO: test samples on thumb target..
|
|
250
|
|
251
|
362
|
252 if __name__ == '__main__':
|
|
253 unittest.main()
|
377
|
254
|