1 using System;
2 using System.Collections;
3 using Span = System.Lex.Span;
4 using cmsx.object;
5
6 namespace cmsx.assembly
7 {
8 public class AssemblyInstruction
9 {
10 public virtual default ~AssemblyInstruction();
11 public virtual void Assemble(Assembler& assembler, Instruction* inst)
12 {
13 Error("assembly instruction for '" + inst->opCode->name + "' not implemented", inst->span);
14 }
15 }
16
17 public class IsInstruction : AssemblyInstruction
18 {
19 public override void Assemble(Assembler& assembler, Instruction* inst)
20 {
21 Stage prevStage = assembler.stage;
22 assembler.stage = Stage.assemble;
23 OperandList& operandList = *inst->operandList;
24 if (operandList.operands.Count() == 1)
25 {
26 if (!inst->label.IsNull())
27 {
28 Stage prevStage = assembler.stage;
29 assembler.stage = Stage.is_;
30 inst->label->Accept(assembler);
31 assembler.stage = prevStage;
32 Symbol* symbol = assembler.currentSymbol;
33 if (symbol != null)
34 {
35 Value x = assembler.Evaluate(operandList.operands[0].Get());
36 if (x.GetFlag(Value.Flag.pure) || x.flags == Value.Flag.register)
37 {
38 symbol->value = x;
39 }
40 else
41 {
42 Error("operand of " + inst->opCode->name + " instruction not defined", inst->span);
43 }
44 }
45 else
46 {
47 Error("label of " + inst->opCode->name + " instruction not defined", inst->span);
48 }
49 }
50 else
51 {
52 Error("label of " + inst->opCode->name + " instruction not defined", inst->span);
53 }
54 }
55 else
56 {
57 Error("IS needs one operand", inst->span);
58 }
59 assembler.stage = prevStage;
60 }
61 }
62
63 public class ExternInstruction : AssemblyInstruction
64 {
65 public override void Assemble(Assembler& assembler, Instruction* inst)
66 {
67 Stage prevStage = assembler.stage;
68 assembler.stage = Stage.setExternal;
69 OperandList& operandList = *inst->operandList;
70 if (inst->operandList->operands.Count() > 0)
71 {
72 inst->operandList->Accept(assembler);
73 }
74 else
75 {
76 Error("EXTERN needs at least one operand", inst->span);
77 }
78 assembler.stage = prevStage;
79 }
80 }
81
82 public class LinkOnceInstruction : AssemblyInstruction
83 {
84 public override void Assemble(Assembler& assembler, Instruction* inst)
85 {
86 Stage prevStage = assembler.stage;
87 assembler.stage = Stage.setLinkOnce;
88 OperandList& operandList = *inst->operandList;
89 if (inst->operandList->operands.Count() > 0)
90 {
91 inst->operandList->Accept(assembler);
92 }
93 else
94 {
95 Error("LINKONCE needs at least one operand", inst->span);
96 }
97 assembler.stage = prevStage;
98 }
99 }
100
101 public class ByteInstruction : AssemblyInstruction
102 {
103 public override void Assemble(Assembler& assembler, Instruction* inst)
104 {
105 if (inst->operandList->operands.Count() > 0)
106 {
107 Stage prevStage = assembler.stage;
108 assembler.stage = Stage.bytes;
109 inst->operandList->Accept(assembler);
110 assembler.stage = prevStage;
111 }
112 else
113 {
114 Error("BYTE needs at least one operand", inst->span);
115 }
116 }
117 }
118
119 public class WydeInstruction : AssemblyInstruction
120 {
121 public override void Assemble(Assembler& assembler, Instruction* inst)
122 {
123 if (inst->operandList->operands.Count() > 0)
124 {
125 Stage prevStage = assembler.stage;
126 assembler.stage = Stage.wydes;
127 inst->operandList->Accept(assembler);
128 assembler.stage = prevStage;
129 }
130 else
131 {
132 Error("WYDE needs at least one operand", inst->span);
133 }
134 }
135 }
136
137 public class TetraInstruction : AssemblyInstruction
138 {
139 public override void Assemble(Assembler& assembler, Instruction* inst)
140 {
141 if (inst->operandList->operands.Count() > 0)
142 {
143 Stage prevStage = assembler.stage;
144 assembler.stage = Stage.tetras;
145 inst->operandList->Accept(assembler);
146 assembler.stage = prevStage;
147 }
148 else
149 {
150 Error("TETRA needs at least one operand", inst->span);
151 }
152 }
153 }
154
155 public class OctaInstruction : AssemblyInstruction
156 {
157 public override void Assemble(Assembler& assembler, Instruction* inst)
158 {
159 OperandList& operandList = *inst->operandList;
160 if (operandList.operands.Count() > 0)
161 {
162 if (assembler.inSpec)
163 {
164 Stage prevStage = assembler.stage;
165 assembler.stage = Stage.spec;
166 Value discriminator = assembler.Evaluate(operandList.operands[0].Get());
167 if (discriminator.value == FILEINFO)
168 {
169 if (operandList.operands.Count() == 3)
170 {
171 Stage prevStage = assembler.stage;
172 assembler.stage = Stage.fileInfo;
173 assembler.Evaluate(operandList.operands[1].Get());
174 string sourceFileName = assembler.str;
175 Value sourceFileNameId = assembler.Evaluate(operandList.operands[2].Get());
176 if (assembler.objectFile.debugSection is DebugSection*)
177 {
178 DebugSection* debugSection = cast<DebugSection*>(assembler.objectFile.debugSection);
179 debugSection->EmitSourceFileName(sourceFileName, cast<uint>(sourceFileNameId.value));
180 }
181 else
182 {
183 Error("debug section expected", inst->span);
184 }
185 assembler.stage = prevStage;
186 }
187 else
188 {
189 Error("OCTA in SPEC file info needs two operands", inst->span);
190 }
191 }
192 else if (discriminator.value == FUNCINFO)
193 {
194 Stage prevStage = assembler.stage;
195 assembler.stage = Stage.funcInfo;
196 if (operandList.operands.Count() == 5)
197 {
198 Value function = assembler.Evaluate(operandList.operands[1].Get());
199 if (function.symbol != null)
200 {
201 if (function.symbol->index != -1)
202 {
203 uint functionSymbolIndex = cast<uint>(function.symbol->index);
204 assembler.Evaluate(operandList.operands[2].Get());
205 string functionFullName = assembler.str;
206 if (!functionFullName.IsEmpty())
207 {
208 Value sourceFileNameId = assembler.Evaluate(operandList.operands[3].Get());
209 Value frameSize = assembler.Evaluate(operandList.operands[4].Get());
210 FunctionInfo functionInfo(functionSymbolIndex, functionFullName, cast<uint>(sourceFileNameId.value), cast<uint>(frameSize.value));
211 if (assembler.objectFile.debugSection is DebugSection*)
212 {
213 DebugSection* debugSection = cast<DebugSection*>(assembler.objectFile.debugSection);
214 debugSection->EmitFunctionInfo(functionInfo);
215 }
216 else
217 {
218 Error("debug section expected", inst->span);
219 }
220 }
221 else
222 {
223 Error("third operand of OCTA in SPEC function info instruction must be a string", inst->span);
224 }
225 }
226 else
227 {
228 Error("second operand of OCTA in SPEC function info instruction must be a defined function symbol", inst->span);
229 }
230 }
231 else
232 {
233 Error("second operand of OCTA in SPEC function info instruction must be a function symbol", inst->span);
234 }
235 }
236 else
237 {
238 Error("OCTA in SPEC function info needs five operands", inst->span);
239 }
240 assembler.stage = prevStage;
241 }
242 else if (discriminator.value == LINEINFO)
243 {
244 Stage prevStage = assembler.stage;
245 assembler.stage = Stage.lineInfo;
246 if (operandList.operands.Count() == 2)
247 {
248 Symbol* currentFunctionSymbol = assembler.currentFunctionSymbol;
249 Value line = assembler.Evaluate(operandList.operands[1].Get());
250 uint offset = cast<uint>(assembler.currentSection->BaseAddress() + assembler.currentSection->Address() - currentFunctionSymbol->start);
251 LineInfo lineInfo(offset, cast<uint>(line.value));
252 if (assembler.objectFile.debugSection is DebugSection*)
253 {
254 DebugSection* debugSection = cast<DebugSection*>(assembler.objectFile.debugSection);
255 debugSection->EmitLineInfo(lineInfo);
256 }
257 else
258 {
259 Error("debug section expected", inst->span);
260 }
261 }
262 else
263 {
264 Error("OCTA in SPEC line info needs two operands", inst->span);
265 }
266 assembler.stage = prevStage;
267 }
268 else if (discriminator.value == BEGINTRY)
269 {
270 Stage prevStage = assembler.stage;
271 assembler.stage = Stage.exceptionInfo;
272 if (operandList.operands.Count() == 3)
273 {
274 Value tryBlockId = assembler.Evaluate(operandList.operands[1].Get());
275 Value parentTryBlockId = assembler.Evaluate(operandList.operands[2].Get());
276 if (assembler.objectFile.debugSection is DebugSection*)
277 {
278 DebugSection* debugSection = cast<DebugSection*>(assembler.objectFile.debugSection);
279 uint offset = cast<uint>(assembler.currentSection->BaseAddress() + assembler.currentSection->Address() - assembler.currentFunctionSymbol->start);
280 debugSection->EmitBeginTry(cast<uint>(tryBlockId.value), cast<uint>(parentTryBlockId.value), offset);
281 }
282 else
283 {
284 Error("debug section expected", inst->span);
285 }
286 }
287 else
288 {
289 Error("OCTA in SPEC begin try needs three operands", inst->span);
290 }
291 assembler.stage = prevStage;
292 }
293 else if (discriminator.value == ENDTRY)
294 {
295 Stage prevStage = assembler.stage;
296 assembler.stage = Stage.exceptionInfo;
297 if (operandList.operands.Count() == 2)
298 {
299 Value tryBlockId = assembler.Evaluate(operandList.operands[1].Get());
300 if (assembler.objectFile.debugSection is DebugSection*)
301 {
302 DebugSection* debugSection = cast<DebugSection*>(assembler.objectFile.debugSection);
303 uint offset = cast<uint>(assembler.currentSection->BaseAddress() + assembler.currentSection->Address() - assembler.currentFunctionSymbol->start);
304 debugSection->EmitEndTry(cast<uint>(tryBlockId.value), offset);
305 }
306 else
307 {
308 Error("debug section expected", inst->span);
309 }
310 }
311 else
312 {
313 Error("OCTA in SPEC end try needs two operands", inst->span);
314 }
315 assembler.stage = prevStage;
316 }
317 else if (discriminator.value == CATCH)
318 {
319 Stage prevStage = assembler.stage;
320 assembler.stage = Stage.exceptionInfo;
321 if (operandList.operands.Count() == 5)
322 {
323 Value catchBlockId = assembler.Evaluate(operandList.operands[1].Get());
324 Value tryBlockId = assembler.Evaluate(operandList.operands[2].Get());
325 Value catchedTypeId1 = assembler.Evaluate(operandList.operands[3].Get());
326 Value catchedTypeId2 = assembler.Evaluate(operandList.operands[4].Get());
327 if (assembler.objectFile.debugSection is DebugSection*)
328 {
329 DebugSection* debugSection = cast<DebugSection*>(assembler.objectFile.debugSection);
330 debugSection->EmitCatch(cast<uint>(catchBlockId.value), cast<uint>(tryBlockId.value), catchedTypeId1.value, catchedTypeId2.value);
331 }
332 else
333 {
334 Error("debug section expected", inst->span);
335 }
336 }
337 else
338 {
339 Error("OCTA in SPEC catch needs five operands", inst->span);
340 }
341 assembler.stage = prevStage;
342 }
343 else if (discriminator.value == BEGINCLEANUP)
344 {
345 Stage prevStage = assembler.stage;
346 assembler.stage = Stage.exceptionInfo;
347 if (operandList.operands.Count() == 3)
348 {
349 Value cleanupBlockId = assembler.Evaluate(operandList.operands[1].Get());
350 Value tryBlockId = assembler.Evaluate(operandList.operands[2].Get());
351 if (assembler.objectFile.debugSection is DebugSection*)
352 {
353 DebugSection* debugSection = cast<DebugSection*>(assembler.objectFile.debugSection);
354 uint offset = cast<uint>(assembler.currentSection->BaseAddress() + assembler.currentSection->Address() - assembler.currentFunctionSymbol->start);
355 debugSection->EmitBeginCleanup(cast<uint>(cleanupBlockId.value), cast<uint>(tryBlockId.value), offset);
356 }
357 else
358 {
359 Error("debug section expected", inst->span);
360 }
361 }
362 else
363 {
364 Error("OCTA in SPEC begin cleanup needs three operands", inst->span);
365 }
366 assembler.stage = prevStage;
367 }
368 else if (discriminator.value == ENDCLEANUP)
369 {
370 Stage prevStage = assembler.stage;
371 assembler.stage = Stage.exceptionInfo;
372 if (operandList.operands.Count() == 2)
373 {
374 Value cleanupBlockId = assembler.Evaluate(operandList.operands[1].Get());
375 if (assembler.objectFile.debugSection is DebugSection*)
376 {
377 DebugSection* debugSection = cast<DebugSection*>(assembler.objectFile.debugSection);
378 uint offset = cast<uint>(assembler.currentSection->BaseAddress() + assembler.currentSection->Address() - assembler.currentFunctionSymbol->start);
379 debugSection->EmitEndCleanup(cast<uint>(cleanupBlockId.value), offset);
380 }
381 else
382 {
383 Error("debug section expected", inst->span);
384 }
385 }
386 else
387 {
388 Error("OCTA in SPEC begin cleanup needs two operands", inst->span);
389 }
390 assembler.stage = prevStage;
391 }
392 else
393 {
394 Error("unknown discriminator for OCTA in SPEC", inst->span);
395 }
396 assembler.stage = prevStage;
397 }
398 else
399 {
400 Stage prevStage = assembler.stage;
401 assembler.stage = Stage.octas;
402 inst->operandList->Accept(assembler);
403 assembler.stage = prevStage;
404 }
405 }
406 else
407 {
408 Error("OCTA needs at least one operand", inst->span);
409 }
410 }
411 }
412
413 public class LoadInstruction : AssemblyInstruction
414 {
415 public override void Assemble(Assembler& assembler, Instruction* inst)
416 {
417 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
418 byte opCode = cast<byte>(inst->opCode->value);
419 Stage prevStage = assembler.stage;
420 assembler.stage = Stage.assemble;
421 OperandList& operandList = *inst->operandList;
422 if (operandList.operands.Count() >= 2 && operandList.operands.Count() <= 3)
423 {
424 Value x = assembler.Evaluate(operandList.operands[0].Get());
425 Value y = assembler.Evaluate(operandList.operands[1].Get());
426 Value z = Value();
427 if (operandList.operands.Count() == 3)
428 {
429 z = assembler.Evaluate(operandList.operands[2].Get());
430 }
431 if (x.flags == Value.Flag.register)
432 {
433 if (y.flags == Value.Flag.register)
434 {
435 if (z.flags == Value.Flag.register)
436 {
437 assembler.EmitOpCode(opCode);
438 assembler.EmitRegisterValue("X", x);
439 assembler.EmitRegisterValue("Y", y);
440 assembler.EmitRegisterValue("Z", z);
441 }
442 else if (z.GetFlag(Value.Flag.pure))
443 {
444 if (z.value <= MaxValue<byte>())
445 {
446 assembler.EmitOpCode(opCode + 1u);
447 assembler.EmitRegisterValue("X", x);
448 assembler.EmitRegisterValue("Y", y);
449 assembler.EmitPureByteValue("Z", z);
450 }
451 else
452 {
453 assembler.EmitSetReg255Value(z.value);
454 assembler.EmitOpCode(opCode);
455 assembler.EmitRegisterValue("X", x);
456 assembler.EmitRegisterValue("Y", y);
457 assembler.EmitRegisterValue("Z", Value(Value.Flag.register, 255u, null));
458 }
459 }
460 else
461 {
462 Error("if X and Y operands of " + inst->opCode->name + " instruction are registers, Z must be register or pure", inst->span);
463 }
464 }
465 else
466 {
467 if (z.flags == Value.Flag.undefined)
468 {
469 if (y.symbol != null)
470 {
471 assembler.EmitAbsoluteRegisterValue(x, "X", y.symbol);
472 assembler.EmitOpCode(opCode + 1u);
473 assembler.EmitRegisterValue("X", x);
474 assembler.EmitRegisterValue("X", x);
475 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
476 }
477 else
478 {
479 Error("if Z operand of " + inst->opCode->name + " instruction is not defined, YZ must be a symbol", inst->span);
480 }
481 }
482 else
483 {
484 Error("if Z operands of " + inst->opCode->name + " instruction is defined, X and Y must be register numbers", inst->span);
485 }
486 }
487 }
488 else
489 {
490 Error("X operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
491 }
492 }
493 else
494 {
495 Error(inst->opCode->name + " needs two or three operands", inst->span);
496 }
497 assembler.stage = prevStage;
498 }
499 }
500
501 public class StoreInstruction : AssemblyInstruction
502 {
503 public override void Assemble(Assembler& assembler, Instruction* inst)
504 {
505 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
506 byte opCode = cast<byte>(inst->opCode->value);
507 Stage prevStage = assembler.stage;
508 assembler.stage = Stage.assemble;
509 OperandList& operandList = *inst->operandList;
510 if (operandList.operands.Count() >= 2 && operandList.operands.Count() <= 3)
511 {
512 Value x = assembler.Evaluate(operandList.operands[0].Get());
513 Value y = assembler.Evaluate(operandList.operands[1].Get());
514 Value z = Value();
515 if (operandList.operands.Count() == 3)
516 {
517 z = assembler.Evaluate(operandList.operands[2].Get());
518 }
519 if (x.flags == Value.Flag.register)
520 {
521 if (y.flags == Value.Flag.register)
522 {
523 if (z.flags == Value.Flag.register)
524 {
525 assembler.EmitOpCode(opCode);
526 assembler.EmitRegisterValue("X", x);
527 assembler.EmitRegisterValue("Y", y);
528 assembler.EmitRegisterValue("Z", z);
529 }
530 else if (z.GetFlag(Value.Flag.pure))
531 {
532 if (z.value <= MaxValue<byte>())
533 {
534 assembler.EmitOpCode(opCode + 1u);
535 assembler.EmitRegisterValue("X", x);
536 assembler.EmitRegisterValue("Y", y);
537 assembler.EmitPureByteValue("Z", z);
538 }
539 else
540 {
541 assembler.EmitSetReg255Value(z.value);
542 assembler.EmitOpCode(opCode);
543 assembler.EmitRegisterValue("X", x);
544 assembler.EmitRegisterValue("Y", y);
545 assembler.EmitRegisterValue("Z", Value(Value.Flag.register, 255u, null));
546 }
547 }
548 else
549 {
550 Error("if X and Y operands of " + inst->opCode->name + " instruction are registers, Z must be register or pure", inst->span);
551 }
552 }
553 else
554 {
555 if (z.flags == Value.Flag.undefined)
556 {
557 if (y.symbol != null)
558 {
559 assembler.EmitAbsoluteRegisterValue(Value(Value.Flag.register, 255u, null), "X", y.symbol);
560 assembler.EmitOpCode(opCode + 1u);
561 assembler.EmitRegisterValue("X", x);
562 assembler.EmitRegisterValue("Y", Value(Value.Flag.register, 255u, null));
563 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
564 }
565 else
566 {
567 Error("if Z operand of " + inst->opCode->name + " instruction is not defined, YZ must be a symbol", inst->span);
568 }
569 }
570 else
571 {
572 Error("if Z operands of " + inst->opCode->name + " instruction is defined, X and Y must be register numbers", inst->span);
573 }
574 }
575 }
576 else
577 {
578 Error("X operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
579 }
580 }
581 else
582 {
583 Error(inst->opCode->name + " needs two or three operands", inst->span);
584 }
585 assembler.stage = prevStage;
586 }
587 }
588
589 public class StoreConstantInstruction : AssemblyInstruction
590 {
591 public override void Assemble(Assembler& assembler, Instruction* inst)
592 {
593 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
594 byte opCode = cast<byte>(inst->opCode->value);
595 Stage prevStage = assembler.stage;
596 assembler.stage = Stage.assemble;
597 OperandList& operandList = *inst->operandList;
598 if (operandList.operands.Count() >= 2 && operandList.operands.Count() <= 3)
599 {
600 Value x = assembler.Evaluate(operandList.operands[0].Get());
601 Value y = assembler.Evaluate(operandList.operands[1].Get());
602 Value z = Value();
603 if (operandList.operands.Count() == 3)
604 {
605 z = assembler.Evaluate(operandList.operands[2].Get());
606 }
607 if (x.GetFlag(Value.Flag.pure))
608 {
609 if (y.flags == Value.Flag.register)
610 {
611 if (z.flags == Value.Flag.register)
612 {
613 assembler.EmitOpCode(opCode);
614 assembler.EmitPureByteValue("X", x);
615 assembler.EmitRegisterValue("Y", y);
616 assembler.EmitRegisterValue("Z", z);
617 }
618 else if (z.GetFlag(Value.Flag.pure))
619 {
620 if (z.value <= MaxValue<byte>())
621 {
622 assembler.EmitOpCode(opCode + 1u);
623 assembler.EmitPureByteValue("X", x);
624 assembler.EmitRegisterValue("Y", y);
625 assembler.EmitPureByteValue("Z", z);
626 }
627 else
628 {
629 assembler.EmitSetReg255Value(z.value);
630 assembler.EmitOpCode(opCode);
631 assembler.EmitPureByteValue("X", x);
632 assembler.EmitRegisterValue("Y", y);
633 assembler.EmitRegisterValue("Z", Value(Value.Flag.register, 255u, null));
634 }
635 }
636 else
637 {
638 Error("if X and Y operands of " + inst->opCode->name + " instruction are registers, Z must be register or pure", inst->span);
639 }
640 }
641 else
642 {
643 if (z.flags == Value.Flag.undefined)
644 {
645 if (y.symbol != null)
646 {
647 assembler.EmitAbsoluteRegisterValue(Value(Value.Flag.register, 255u, null), "X", y.symbol);
648 assembler.EmitOpCode(opCode + 1u);
649 assembler.EmitRegisterValue("X", x);
650 assembler.EmitRegisterValue("Y", Value(Value.Flag.register, 255u, null));
651 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
652 }
653 else
654 {
655 Error("if Z operand of " + inst->opCode->name + " instruction is not defined, YZ must be a symbol", inst->span);
656 }
657 }
658 else
659 {
660 Error("if Z operands of " + inst->opCode->name + " instruction is defined, X and Y must be register numbers", inst->span);
661 }
662 }
663 }
664 else
665 {
666 Error("X operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
667 }
668 }
669 else
670 {
671 Error(inst->opCode->name + " needs two or three operands", inst->span);
672 }
673 assembler.stage = prevStage;
674 }
675 }
676
677 public class RegisterInstruction : AssemblyInstruction
678 {
679 public override void Assemble(Assembler& assembler, Instruction* inst)
680 {
681 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256 || inst->opCode->value == LDA);
682 byte opCode = cast<byte>(inst->opCode->value);
683 if (inst->opCode->value == LDA)
684 {
685 opCode = cmsx.machine.ADDU;
686 }
687 Stage prevStage = assembler.stage;
688 assembler.stage = Stage.assemble;
689 OperandList& operandList = *inst->operandList;
690 if (operandList.operands.Count() >= 2 && operandList.operands.Count() <= 3)
691 {
692 Value x = assembler.Evaluate(operandList.operands[0].Get());
693 Value y = assembler.Evaluate(operandList.operands[1].Get());
694 Value z = Value();
695 if (operandList.operands.Count() == 3)
696 {
697 z = assembler.Evaluate(operandList.operands[2].Get());
698 }
699 if (x.flags == Value.Flag.register && y.flags == Value.Flag.register)
700 {
701 if (z.flags == Value.Flag.register)
702 {
703 assembler.EmitOpCode(opCode);
704 assembler.EmitRegisterValue("X", x);
705 assembler.EmitRegisterValue("Y", y);
706 assembler.EmitRegisterValue("Z", z);
707 }
708 else if (z.GetFlag(Value.Flag.pure))
709 {
710 if (z.value <= MaxValue<byte>())
711 {
712 assembler.EmitOpCode(opCode + 1u);
713 assembler.EmitRegisterValue("X", x);
714 assembler.EmitRegisterValue("Y", y);
715 assembler.EmitPureByteValue("Z", z);
716 }
717 else
718 {
719 assembler.EmitSetReg255Value(z.value);
720 assembler.EmitOpCode(opCode);
721 assembler.EmitRegisterValue("X", x);
722 assembler.EmitRegisterValue("Y", y);
723 assembler.EmitRegisterValue("Z", Value(Value.Flag.register, 255u, null));
724 }
725 }
726 else if (z.flags == Value.Flag.undefined)
727 {
728 assembler.EmitOpCode(opCode + 1u);
729 assembler.EmitRegisterValue("X", x);
730 assembler.EmitRegisterValue("Y", y);
731 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
732 }
733 }
734 else
735 {
736 Error("X and Y operands of " + inst->opCode->name + " instruction must be register numbers", inst->span);
737 }
738 }
739 else
740 {
741 Error(inst->opCode->name + " needs two or three operands", inst->span);
742 }
743 assembler.stage = prevStage;
744 }
745 }
746
747 public class FloatingPointInstruction : AssemblyInstruction
748 {
749 public override void Assemble(Assembler& assembler, Instruction* inst)
750 {
751 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256 || inst->opCode->value == LDA);
752 byte opCode = cast<byte>(inst->opCode->value);
753 if (inst->opCode->value == LDA)
754 {
755 opCode = cmsx.machine.ADDU;
756 }
757 Stage prevStage = assembler.stage;
758 assembler.stage = Stage.assemble;
759 OperandList& operandList = *inst->operandList;
760 if (operandList.operands.Count() == 3 )
761 {
762 Value x = assembler.Evaluate(operandList.operands[0].Get());
763 Value y = assembler.Evaluate(operandList.operands[1].Get());
764 Value z = assembler.Evaluate(operandList.operands[2].Get());
765 if (x.flags == Value.Flag.register && y.flags == Value.Flag.register && z.flags == Value.Flag.register)
766 {
767 assembler.EmitOpCode(opCode);
768 assembler.EmitRegisterValue("X", x);
769 assembler.EmitRegisterValue("Y", y);
770 assembler.EmitRegisterValue("Z", z);
771 }
772 else
773 {
774 Error("all operands of " + inst->opCode->name + " instruction must be register numbers", inst->span);
775 }
776 }
777 else
778 {
779 Error(inst->opCode->name + " needs three operands", inst->span);
780 }
781 assembler.stage = prevStage;
782 }
783 }
784
785 public class SetInstruction : AssemblyInstruction
786 {
787 public override void Assemble(Assembler& assembler, Instruction* inst)
788 {
789 Stage prevStage = assembler.stage;
790 assembler.stage = Stage.assemble;
791 OperandList& operandList = *inst->operandList;
792 if (operandList.operands.Count() == 2)
793 {
794 Value x = assembler.Evaluate(operandList.operands[0].Get());
795 Value y = assembler.Evaluate(operandList.operands[1].Get());
796 if (x.flags == Value.Flag.register)
797 {
798 if (y.flags == Value.Flag.register)
799 {
800 assembler.EmitOpCode(cmsx.machine.ORI);
801 assembler.EmitRegisterValue("X", x);
802 assembler.EmitRegisterValue("Y", y);
803 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
804 }
805 else if (y.GetFlag(Value.Flag.pure))
806 {
807 ulong value = y.value;
808 if (value <= MaxValue<ushort>())
809 {
810 byte b0 = cast<byte>(value);
811 value = value >> 8u;
812 byte b1 = cast<byte>(value);
813 value = value >> 8u;
814 assembler.EmitOpCode(cmsx.machine.SETL);
815 assembler.EmitRegisterValue("X", x);
816 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, b1, null));
817 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, b0, null));
818 }
819 else if (value <= MaxValue<uint>())
820 {
821 byte b0 = cast<byte>(value);
822 value = value >> 8u;
823 byte b1 = cast<byte>(value);
824 value = value >> 8u;
825 byte b2 = cast<byte>(value);
826 value = value >> 8u;
827 byte b3 = cast<byte>(value);
828 value = value >> 8u;
829 assembler.EmitOpCode(cmsx.machine.SETML);
830 assembler.EmitRegisterValue("X", x);
831 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, b3, null));
832 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, b2, null));
833 assembler.EmitOpCode(cmsx.machine.ORL);
834 assembler.EmitRegisterValue("X", x);
835 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, b1, null));
836 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, b0, null));
837 }
838 else
839 {
840 byte b0 = cast<byte>(value);
841 value = value >> 8u;
842 byte b1 = cast<byte>(value);
843 value = value >> 8u;
844 byte b2 = cast<byte>(value);
845 value = value >> 8u;
846 byte b3 = cast<byte>(value);
847 value = value >> 8u;
848 byte b4 = cast<byte>(value);
849 value = value >> 8u;
850 byte b5 = cast<byte>(value);
851 value = value >> 8u;
852 byte b6 = cast<byte>(value);
853 value = value >> 8u;
854 byte b7 = cast<byte>(value);
855 value = value >> 8u;
856 assembler.EmitOpCode(cmsx.machine.SETH);
857 assembler.EmitRegisterValue("X", x);
858 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, b7, null));
859 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, b6, null));
860 assembler.EmitOpCode(cmsx.machine.ORMH);
861 assembler.EmitRegisterValue("X", x);
862 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, b5, null));
863 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, b4, null));
864 assembler.EmitOpCode(cmsx.machine.ORML);
865 assembler.EmitRegisterValue("X", x);
866 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, b3, null));
867 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, b2, null));
868 assembler.EmitOpCode(cmsx.machine.ORL);
869 assembler.EmitRegisterValue("X", x);
870 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, b1, null));
871 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, b0, null));
872 }
873 }
874 else
875 {
876 Error("Y operand of " + inst->opCode->name + " instruction must be a register number or a pure value", inst->span);
877 }
878 }
879 else
880 {
881 Error("X operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
882 }
883 }
884 else
885 {
886 Error(inst->opCode->name + " needs two operands", inst->span);
887 }
888 assembler.stage = prevStage;
889 }
890 }
891
892 public class NegateInstruction : AssemblyInstruction
893 {
894 public override void Assemble(Assembler& assembler, Instruction* inst)
895 {
896 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
897 byte opCode = cast<byte>(inst->opCode->value);
898 Stage prevStage = assembler.stage;
899 assembler.stage = Stage.assemble;
900 OperandList& operandList = *inst->operandList;
901 if (operandList.operands.Count() == 2 || operandList.operands.Count() == 3)
902 {
903 Value x = assembler.Evaluate(operandList.operands[0].Get());
904 Value y = assembler.Evaluate(operandList.operands[1].Get());
905 Value z = Value();
906 if (operandList.operands.Count() == 3)
907 {
908 z = assembler.Evaluate(operandList.operands[2].Get());
909 }
910 if (x.flags == Value.Flag.register)
911 {
912 if (y.GetFlag(Value.Flag.pure))
913 {
914 if (z.flags == Value.Flag.register)
915 {
916 assembler.EmitOpCode(opCode);
917 assembler.EmitRegisterValue("X", x);
918 assembler.EmitPureByteValue("Y", y);
919 assembler.EmitRegisterValue("Z", z);
920 }
921 else if (z.GetFlag(Value.Flag.pure))
922 {
923 if (z.value <= MaxValue<byte>())
924 {
925 assembler.EmitOpCode(opCode + 1u);
926 assembler.EmitRegisterValue("X", x);
927 assembler.EmitPureByteValue("Y", y);
928 assembler.EmitPureByteValue("Z", z);
929 }
930 else
931 {
932 assembler.EmitSetReg255Value(z.value);
933 assembler.EmitOpCode(opCode);
934 assembler.EmitPureByteValue("X", x);
935 assembler.EmitPureByteValue("Y", y);
936 assembler.EmitRegisterValue("Z", Value(Value.Flag.register, 255u, null));
937 }
938 }
939 else if (z.flags == Value.Flag.undefined)
940 {
941 assembler.EmitOpCode(opCode + 1u);
942 assembler.EmitPureByteValue("X", x);
943 assembler.EmitRegisterValue("Y", y);
944 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
945 }
946 }
947 else if (y.flags == Value.Flag.register)
948 {
949 if (z.flags == Value.Flag.undefined)
950 {
951 assembler.EmitOpCode(opCode);
952 assembler.EmitRegisterValue("X", x);
953 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, 0u, null));
954 assembler.EmitRegisterValue("Z", y);
955 }
956 else
957 {
958 Error("If X and Y operands of " + inst->opCode->name + " instruction are register numbers, Z must be undefined", inst->span);
959 }
960 }
961 }
962 else
963 {
964 Error("X operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
965 }
966 }
967 else
968 {
969 Error(inst->opCode->name + " needs two or three operands", inst->span);
970 }
971 assembler.stage = prevStage;
972 }
973 }
974
975 public class FloatingRoundingInstruction : AssemblyInstruction
976 {
977 public override void Assemble(Assembler& assembler, Instruction* inst)
978 {
979 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
980 byte opCode = cast<byte>(inst->opCode->value);
981 Stage prevStage = assembler.stage;
982 assembler.stage = Stage.assemble;
983 OperandList& operandList = *inst->operandList;
984 if (operandList.operands.Count() == 2 || operandList.operands.Count() == 3)
985 {
986 Value x = assembler.Evaluate(operandList.operands[0].Get());
987 Value y = assembler.Evaluate(operandList.operands[1].Get());
988 Value z = Value();
989 if (operandList.operands.Count() == 3)
990 {
991 z = assembler.Evaluate(operandList.operands[2].Get());
992 }
993 if (x.flags == Value.Flag.register && y.flags == Value.Flag.register && z.flags == Value.Flag.undefined)
994 {
995 assembler.EmitOpCode(opCode);
996 assembler.EmitRegisterValue("X", x);
997 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, 1u, null));
998 assembler.EmitRegisterValue("Z", y);
999 }
1000 else if (x.flags == Value.Flag.register && y.GetFlag(Value.Flag.pure) && z.flags == Value.Flag.register)
1001 {
1002 assembler.EmitOpCode(opCode);
1003 assembler.EmitRegisterValue("X", x);
1004 assembler.EmitPureByteValue("Y", y);
1005 assembler.EmitRegisterValue("Z", z);
1006 }
1007 else
1008 {
1009 Error(inst->opCode->name + " instruction needs X (register), Y (pure), Z (register), or X (register), Z (register) operands", inst->span);
1010 }
1011 }
1012 else
1013 {
1014 Error(inst->opCode->name + " needs two or three operands", inst->span);
1015 }
1016 assembler.stage = prevStage;
1017 }
1018 }
1019
1020 public class WydeImmediateInstruction : AssemblyInstruction
1021 {
1022 public override void Assemble(Assembler& assembler, Instruction* inst)
1023 {
1024 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
1025 byte opCode = cast<byte>(inst->opCode->value);
1026 Stage prevStage = assembler.stage;
1027 assembler.stage = Stage.assemble;
1028 OperandList& operandList = *inst->operandList;
1029 if (operandList.operands.Count() == 2)
1030 {
1031 Value x = assembler.Evaluate(operandList.operands[0].Get());
1032 Value y = assembler.Evaluate(operandList.operands[1].Get());
1033 if (x.flags == Value.Flag.register)
1034 {
1035 if (y.GetFlag(Value.Flag.pure) && y.value <= MaxValue<ushort>())
1036 {
1037 ulong value = y.value;
1038 byte b0 = cast<byte>(value);
1039 value = value >> 8u;
1040 byte b1 = cast<byte>(value);
1041 value = value >> 8u;
1042 assembler.EmitOpCode(opCode);
1043 assembler.EmitRegisterValue("X", x);
1044 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, b1, null));
1045 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, b0, null));
1046 }
1047 else
1048 {
1049 Error("Y operand of " + inst->opCode->name + " instruction too big", inst->span);
1050 }
1051 }
1052 else
1053 {
1054 Error("X operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
1055 }
1056 }
1057 else
1058 {
1059 Error(inst->opCode->name + " needs two operands", inst->span);
1060 }
1061 assembler.stage = prevStage;
1062 }
1063 }
1064
1065 public class JumpInstruction : AssemblyInstruction
1066 {
1067 public override void Assemble(Assembler& assembler, Instruction* inst)
1068 {
1069 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
1070 byte opCode = cast<byte>(inst->opCode->value);
1071 Stage prevStage = assembler.stage;
1072 assembler.stage = Stage.assemble;
1073 OperandList& operandList = *inst->operandList;
1074 if (operandList.operands.Count() == 1)
1075 {
1076 Value x = assembler.Evaluate(operandList.operands[0].Get());
1077 Symbol* symbol = x.symbol;
1078 if (symbol != null)
1079 {
1080 if (symbol->linkage == Linkage.internal_ || symbol->linkage == Linkage.external)
1081 {
1082 if (symbol->value.GetFlag(Value.Flag.address))
1083 {
1084 ulong to = symbol->value.value;
1085 ulong at = assembler.currentSection->Address();
1086 if (at >= to)
1087 {
1088 ulong offset = (at - to) >> 2u;
1089 if (offset <= (cast<ulong>(MaxValue<ushort>()) << 8u))
1090 {
1091 assembler.EmitOpCode(cmsx.machine.JMPB);
1092 assembler.EmitLongOffset(cast<uint>(offset));
1093 }
1094 else
1095 {
1096 Error(inst->opCode->name + " too far", inst->span);
1097 }
1098 }
1099 else
1100 {
1101 ulong offset = (to - at) >> 2u;
1102 if (offset <= (cast<ulong>(MaxValue<ushort>()) << 8u))
1103 {
1104 assembler.EmitOpCode(cmsx.machine.JMP);
1105 assembler.EmitLongOffset(cast<uint>(offset));
1106 }
1107 else
1108 {
1109 Error(inst->opCode->name + " too far", inst->span);
1110 }
1111 }
1112 }
1113 else if (symbol->value.flags == Value.Flag.undefined)
1114 {
1115 assembler.EmitForwardLongJump(symbol);
1116 }
1117 else
1118 {
1119 Error("symbol operand of " + inst->opCode->name + " instruction cannot be a register number", inst->span);
1120 }
1121 }
1122 else if (symbol->linkage == Linkage.undefined)
1123 {
1124 Error(inst->opCode->name + " to undefined symbol", inst->span);
1125 }
1126 }
1127 else
1128 {
1129 Error("X operand of " + inst->opCode->name + " instruction must be a symbol", inst->span);
1130 }
1131 }
1132 else
1133 {
1134 Error(inst->opCode->name + " needs one operand", inst->span);
1135 }
1136 assembler.stage = prevStage;
1137 }
1138 }
1139
1140 public class GoInstruction : AssemblyInstruction
1141 {
1142 public override void Assemble(Assembler& assembler, Instruction* inst)
1143 {
1144 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
1145 byte opCode = cast<byte>(inst->opCode->value);
1146 Stage prevStage = assembler.stage;
1147 assembler.stage = Stage.assemble;
1148 OperandList& operandList = *inst->operandList;
1149 if (operandList.operands.Count() >= 2 && operandList.operands.Count() <= 3)
1150 {
1151 Value x = assembler.Evaluate(operandList.operands[0].Get());
1152 Value y = assembler.Evaluate(operandList.operands[1].Get());
1153 Value z = Value();
1154 if (operandList.operands.Count() == 3)
1155 {
1156 z = assembler.Evaluate(operandList.operands[2].Get());
1157 }
1158 if (x.flags == Value.Flag.register)
1159 {
1160 if (y.flags == Value.Flag.register)
1161 {
1162 if (z.flags == Value.Flag.register)
1163 {
1164 assembler.EmitOpCode(opCode);
1165 assembler.EmitRegisterValue("X", x);
1166 assembler.EmitRegisterValue("Y", y);
1167 assembler.EmitRegisterValue("Z", z);
1168 }
1169 else if (z.GetFlag(Value.Flag.pure))
1170 {
1171 if (z.value <= MaxValue<byte>())
1172 {
1173 assembler.EmitOpCode(opCode + 1u);
1174 assembler.EmitRegisterValue("X", x);
1175 assembler.EmitRegisterValue("Y", y);
1176 assembler.EmitPureByteValue("Z", z);
1177 }
1178 else
1179 {
1180 assembler.EmitSetReg255Value(z.value);
1181 assembler.EmitOpCode(opCode);
1182 assembler.EmitRegisterValue("X", x);
1183 assembler.EmitRegisterValue("Y", y);
1184 assembler.EmitRegisterValue("Z", Value(Value.Flag.register, 255u, null));
1185 }
1186 }
1187 else if (z.flags == Value.Flag.undefined)
1188 {
1189 assembler.EmitOpCode(opCode + 1u);
1190 assembler.EmitRegisterValue("X", x);
1191 assembler.EmitRegisterValue("Y", y);
1192 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
1193 }
1194 }
1195 else if (y.symbol != null)
1196 {
1197 assembler.EmitAbsoluteRegisterValue(x, "X", y.symbol);
1198 if (z.flags == Value.Flag.register)
1199 {
1200 assembler.EmitOpCode(opCode);
1201 assembler.EmitRegisterValue("X", x);
1202 assembler.EmitRegisterValue("X", x);
1203 assembler.EmitRegisterValue("Z", z);
1204 }
1205 else if (z.GetFlag(Value.Flag.pure))
1206 {
1207 if (z.value <= MaxValue<byte>())
1208 {
1209 assembler.EmitOpCode(opCode + 1u);
1210 assembler.EmitRegisterValue("X", x);
1211 assembler.EmitRegisterValue("X", x);
1212 assembler.EmitPureByteValue("Z", z);
1213 }
1214 else
1215 {
1216 Error("Z operand of " + inst->opCode->name + " instruction must be either a register number or a pure byte value", inst->span);
1217 }
1218 }
1219 else if (z.flags == Value.Flag.undefined)
1220 {
1221 assembler.EmitOpCode(opCode + 1u);
1222 assembler.EmitRegisterValue("X", x);
1223 assembler.EmitRegisterValue("X", x);
1224 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
1225 }
1226 }
1227 else
1228 {
1229 Error("Y operand of " + inst->opCode->name + " instruction must be either a register number or a symbol", inst->span);
1230 }
1231 }
1232 else
1233 {
1234 Error("X operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
1235 }
1236 }
1237 else
1238 {
1239 Error(inst->opCode->name + " needs two or three operands", inst->span);
1240 }
1241 assembler.stage = prevStage;
1242 }
1243 }
1244
1245 public class CallInstruction : AssemblyInstruction
1246 {
1247 public override void Assemble(Assembler& assembler, Instruction* inst)
1248 {
1249 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
1250 byte opCode = cast<byte>(inst->opCode->value);
1251 Stage prevStage = assembler.stage;
1252 assembler.stage = Stage.assemble;
1253 OperandList& operandList = *inst->operandList;
1254 if (operandList.operands.Count() >= 2 && operandList.operands.Count() <= 3)
1255 {
1256 Value x = assembler.Evaluate(operandList.operands[0].Get());
1257 Value y = assembler.Evaluate(operandList.operands[1].Get());
1258 Value z = Value();
1259 if (operandList.operands.Count() == 3)
1260 {
1261 z = assembler.Evaluate(operandList.operands[2].Get());
1262 }
1263 if (x.flags == Value.Flag.register)
1264 {
1265 if (y.symbol != null)
1266 {
1267 assembler.EmitAbsoluteRegisterValue(x, "X", y.symbol);
1268 if (z.flags == Value.Flag.register)
1269 {
1270 assembler.EmitOpCode(opCode);
1271 assembler.EmitRegisterValue("X", x);
1272 assembler.EmitRegisterValue("X", x);
1273 assembler.EmitRegisterValue("Z", z);
1274 }
1275 else if (z.GetFlag(Value.Flag.pure))
1276 {
1277 if (z.value <= MaxValue<byte>())
1278 {
1279 assembler.EmitOpCode(opCode + 1u);
1280 assembler.EmitRegisterValue("X", x);
1281 assembler.EmitRegisterValue("X", x);
1282 assembler.EmitPureByteValue("Z", z);
1283 }
1284 else
1285 {
1286 Error("Z operand of " + inst->opCode->name + " instruction must be either a register number or a pure byte value", inst->span);
1287 }
1288 }
1289 else if (z.flags == Value.Flag.undefined)
1290 {
1291 assembler.EmitOpCode(opCode + 1u);
1292 assembler.EmitRegisterValue("X", x);
1293 assembler.EmitRegisterValue("X", x);
1294 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
1295 }
1296 }
1297 else if (y.flags == Value.Flag.register)
1298 {
1299 if (z.flags == Value.Flag.register)
1300 {
1301 assembler.EmitOpCode(opCode);
1302 assembler.EmitRegisterValue("X", x);
1303 assembler.EmitRegisterValue("Y", y);
1304 assembler.EmitRegisterValue("Z", z);
1305 }
1306 else if (z.GetFlag(Value.Flag.pure))
1307 {
1308 if (z.value <= MaxValue<byte>())
1309 {
1310 assembler.EmitOpCode(opCode + 1u);
1311 assembler.EmitRegisterValue("X", x);
1312 assembler.EmitRegisterValue("Y", y);
1313 assembler.EmitPureByteValue("Z", z);
1314 }
1315 else
1316 {
1317 Error("Z operand of " + inst->opCode->name + " instruction must be either a register number or a pure byte value", inst->span);
1318 }
1319 }
1320 else if (z.flags == Value.Flag.undefined)
1321 {
1322 assembler.EmitOpCode(opCode + 1u);
1323 assembler.EmitRegisterValue("X", x);
1324 assembler.EmitRegisterValue("Y", y);
1325 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
1326 }
1327 }
1328 else
1329 {
1330 Error("Y operand of " + inst->opCode->name + " instruction must be either a symbol or a register number", inst->span);
1331 }
1332 }
1333 else
1334 {
1335 Error("X operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
1336 }
1337 }
1338 else
1339 {
1340 Error(inst->opCode->name + " needs two or three operands", inst->span);
1341 }
1342 assembler.stage = prevStage;
1343 }
1344 }
1345
1346 public class RetInstruction : AssemblyInstruction
1347 {
1348 public override void Assemble(Assembler& assembler, Instruction* inst)
1349 {
1350 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
1351 byte opCode = cast<byte>(inst->opCode->value);
1352 Stage prevStage = assembler.stage;
1353 assembler.stage = Stage.assemble;
1354 OperandList& operandList = *inst->operandList;
1355 if (operandList.operands.Count() == 1)
1356 {
1357 assembler.EmitOpCode(opCode);
1358 assembler.EmitPureByteValue("X", Value(Value.Flag.pure, 0u, null));
1359 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, 0u, null));
1360 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
1361 }
1362 else
1363 {
1364 Error(inst->opCode->name + " takes no operands", inst->span);
1365 }
1366 assembler.stage = prevStage;
1367 }
1368 }
1369
1370 public class SwymInstruction : AssemblyInstruction
1371 {
1372 public override void Assemble(Assembler& assembler, Instruction* inst)
1373 {
1374 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
1375 byte opCode = cast<byte>(inst->opCode->value);
1376 Stage prevStage = assembler.stage;
1377 assembler.stage = Stage.assemble;
1378 OperandList& operandList = *inst->operandList;
1379 if (operandList.operands.Count() == 1)
1380 {
1381 assembler.EmitOpCode(opCode);
1382 assembler.EmitPureByteValue("X", Value(Value.Flag.pure, 0u, null));
1383 assembler.EmitPureByteValue("Y", Value(Value.Flag.pure, 0u, null));
1384 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
1385 }
1386 else
1387 {
1388 Error(inst->opCode->name + " takes no operands", inst->span);
1389 }
1390 assembler.stage = prevStage;
1391 }
1392 }
1393
1394 public class BranchInstruction : AssemblyInstruction
1395 {
1396 public override void Assemble(Assembler& assembler, Instruction* inst)
1397 {
1398 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
1399 byte opCode = cast<byte>(inst->opCode->value);
1400 Stage prevStage = assembler.stage;
1401 assembler.stage = Stage.assemble;
1402 OperandList& operandList = *inst->operandList;
1403 if (operandList.operands.Count() == 2)
1404 {
1405 Value x = assembler.Evaluate(operandList.operands[0].Get());
1406 Value y = assembler.Evaluate(operandList.operands[1].Get());
1407 if (x.flags == Value.Flag.register)
1408 {
1409 Symbol* symbol = y.symbol;
1410 if (symbol != null)
1411 {
1412 if (symbol->value.GetFlag(Value.Flag.address))
1413 {
1414 ulong to = symbol->value.value;
1415 ulong at = assembler.currentSection->Address();
1416 if (at >= to)
1417 {
1418 ulong offset = (at - to) >> 2u;
1419 if (offset <= cast<ulong>(MaxValue<ushort>()))
1420 {
1421 assembler.EmitOpCode(opCode + 1u);
1422 assembler.EmitRegisterValue("X", x);
1423 assembler.EmitShortOffset(cast<ushort>(offset));
1424 }
1425 else
1426 {
1427 Error(inst->opCode->name + " too far", inst->span);
1428 }
1429 }
1430 else
1431 {
1432 ulong offset = (to - at) >> 2u;
1433 if (offset <= cast<ulong>(MaxValue<ushort>()))
1434 {
1435 assembler.EmitOpCode(opCode);
1436 assembler.EmitRegisterValue("X", x);
1437 assembler.EmitShortOffset(cast<ushort>(offset));
1438 }
1439 else
1440 {
1441 Error(inst->opCode->name + " too far", inst->span);
1442 }
1443 }
1444 }
1445 else if (symbol->value.flags == Value.Flag.undefined)
1446 {
1447 assembler.EmitForwardShortJump("X", opCode, x, symbol);
1448 }
1449 else
1450 {
1451 Error("symbol operand of " + inst->opCode->name + " instruction cannot be a register number", inst->span);
1452 }
1453 }
1454 else
1455 {
1456 Error("Y operand of " + inst->opCode->name + " instruction must be a symbol", inst->span);
1457 }
1458 }
1459 else
1460 {
1461 Error("X operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
1462 }
1463 }
1464 else
1465 {
1466 Error(inst->opCode->name + " needs two operands", inst->span);
1467 }
1468 assembler.stage = prevStage;
1469 }
1470 }
1471
1472 public class TrapInstruction : AssemblyInstruction
1473 {
1474 public override void Assemble(Assembler& assembler, Instruction* inst)
1475 {
1476 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
1477 byte opCode = cast<byte>(inst->opCode->value);
1478 Stage prevStage = assembler.stage;
1479 assembler.stage = Stage.assemble;
1480 OperandList& operandList = *inst->operandList;
1481 if (operandList.operands.Count() == 3)
1482 {
1483 Value x = assembler.Evaluate(operandList.operands[0].Get());
1484 Value y = assembler.Evaluate(operandList.operands[1].Get());
1485 Value z = assembler.Evaluate(operandList.operands[2].Get());
1486 if (x.GetFlag(Value.Flag.pure) && y.GetFlag(Value.Flag.pure) && z.GetFlag(Value.Flag.pure))
1487 {
1488 assembler.EmitOpCode(opCode);
1489 assembler.EmitPureByteValue("X", x);
1490 assembler.EmitPureByteValue("Y", y);
1491 assembler.EmitPureByteValue("Z", z);
1492 }
1493 else
1494 {
1495 Error(inst->opCode->name + " operands must be pure bytes", inst->span);
1496 }
1497 }
1498 else
1499 {
1500 Error(inst->opCode->name + " needs three operands", inst->span);
1501 }
1502 assembler.stage = prevStage;
1503 }
1504 }
1505
1506 public class GetInstruction : AssemblyInstruction
1507 {
1508 public override void Assemble(Assembler& assembler, Instruction* inst)
1509 {
1510 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
1511 byte opCode = cast<byte>(inst->opCode->value);
1512 Stage prevStage = assembler.stage;
1513 assembler.stage = Stage.assemble;
1514 OperandList& operandList = *inst->operandList;
1515 if (operandList.operands.Count() == 2)
1516 {
1517 Value x = assembler.Evaluate(operandList.operands[0].Get());
1518 Value y = assembler.Evaluate(operandList.operands[1].Get());
1519 if (x.flags == Value.Flag.register)
1520 {
1521 if (y.GetFlag(Value.Flag.pure))
1522 {
1523 assembler.EmitOpCode(opCode);
1524 assembler.EmitRegisterValue("X", x);
1525 assembler.EmitPureByteValue("Y", y);
1526 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
1527 }
1528 else
1529 {
1530 Error("Y operand of " + inst->opCode->name + " instruction must be a pure byte", inst->span);
1531 }
1532 }
1533 else
1534 {
1535 Error("X operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
1536 }
1537 }
1538 else
1539 {
1540 Error(inst->opCode->name + " needs two operands", inst->span);
1541 }
1542 assembler.stage = prevStage;
1543 }
1544 }
1545
1546 public class PutInstruction : AssemblyInstruction
1547 {
1548 public override void Assemble(Assembler& assembler, Instruction* inst)
1549 {
1550 #assert(inst->opCode->value >= 0 && inst->opCode->value < 256);
1551 byte opCode = cast<byte>(inst->opCode->value);
1552 Stage prevStage = assembler.stage;
1553 assembler.stage = Stage.assemble;
1554 OperandList& operandList = *inst->operandList;
1555 if (operandList.operands.Count() == 2)
1556 {
1557 Value x = assembler.Evaluate(operandList.operands[0].Get());
1558 Value y = assembler.Evaluate(operandList.operands[1].Get());
1559 if (x.GetFlag(Value.Flag.pure))
1560 {
1561 if (y.flags == Value.Flag.register)
1562 {
1563 assembler.EmitOpCode(opCode);
1564 assembler.EmitPureByteValue("X", x);
1565 assembler.EmitRegisterValue("Y", y);
1566 assembler.EmitPureByteValue("Z", Value(Value.Flag.pure, 0u, null));
1567 }
1568 else
1569 {
1570 Error("Y operand of " + inst->opCode->name + " instruction must be a register number", inst->span);
1571 }
1572 }
1573 else
1574 {
1575 Error("X operand of " + inst->opCode->name + " instruction must be a pure byte", inst->span);
1576 }
1577 }
1578 else
1579 {
1580 Error(inst->opCode->name + " needs two operands", inst->span);
1581 }
1582 assembler.stage = prevStage;
1583 }
1584 }
1585
1586 public class BSpecInstruction : AssemblyInstruction
1587 {
1588 public override void Assemble(Assembler& assembler, Instruction* inst)
1589 {
1590 assembler.specStack.Push(assembler.inSpec);
1591 assembler.inSpec = true;
1592 }
1593 }
1594
1595 public class ESpecInstruction : AssemblyInstruction
1596 {
1597 public override void Assemble(Assembler& assembler, Instruction* inst)
1598 {
1599 assembler.inSpec = assembler.specStack.Pop();
1600 }
1601 }
1602
1603 public class AssemblyInstructionMap
1604 {
1605 static AssemblyInstructionMap() : instance(new AssemblyInstructionMap())
1606 {
1607 }
1608 public static AssemblyInstructionMap& Instance()
1609 {
1610 return *instance;
1611 }
1612 private AssemblyInstructionMap()
1613 {
1614 AssemblyInstruction* assemblyInst = new AssemblyInstruction();
1615 instructionList.Add(UniquePtr<AssemblyInstruction>(assemblyInst));
1616 for (int i = 0; i < numInsts; ++i;)
1617 {
1618 instructions.Add(assemblyInst);
1619 }
1620
1621 IsInstruction* isInst = new IsInstruction();
1622 instructionList.Add(UniquePtr<AssemblyInstruction>(isInst));
1623 instructions[IS] = isInst;
1624 ExternInstruction* externInst = new ExternInstruction();
1625 instructionList.Add(UniquePtr<AssemblyInstruction>(externInst));
1626 instructions[EXTERN] = externInst;
1627 LinkOnceInstruction* linkOnceInst = new LinkOnceInstruction();
1628 instructionList.Add(UniquePtr<AssemblyInstruction>(linkOnceInst));
1629 instructions[LINKONCE] = linkOnceInst;
1630 ByteInstruction* byteInst = new ByteInstruction();
1631 instructionList.Add(UniquePtr<AssemblyInstruction>(byteInst));
1632 instructions[BYTE] = byteInst;
1633 WydeInstruction* wydeInst = new WydeInstruction();
1634 instructionList.Add(UniquePtr<AssemblyInstruction>(wydeInst));
1635 instructions[WYDE] = wydeInst;
1636 TetraInstruction* tetraInst = new TetraInstruction();
1637 instructionList.Add(UniquePtr<AssemblyInstruction>(tetraInst));
1638 instructions[TETRA] = tetraInst;
1639 OctaInstruction* octaInst = new OctaInstruction();
1640 instructionList.Add(UniquePtr<AssemblyInstruction>(octaInst));
1641 instructions[OCTA] = octaInst;
1642 BSpecInstruction* bspecInst = new BSpecInstruction();
1643 instructionList.Add(UniquePtr<AssemblyInstruction>(bspecInst));
1644 instructions[BSPEC] = bspecInst;
1645 ESpecInstruction* especInst = new ESpecInstruction();
1646 instructionList.Add(UniquePtr<AssemblyInstruction>(especInst));
1647 instructions[ESPEC] = especInst;
1648
1649 LoadInstruction* loadInst = new LoadInstruction();
1650 instructionList.Add(UniquePtr<AssemblyInstruction>(loadInst));
1651 instructions[cmsx.machine.LDB] = loadInst;
1652 instructions[cmsx.machine.LDW] = loadInst;
1653 instructions[cmsx.machine.LDT] = loadInst;
1654 instructions[cmsx.machine.LDO] = loadInst;
1655 instructions[cmsx.machine.LDBU] = loadInst;
1656 instructions[cmsx.machine.LDWU] = loadInst;
1657 instructions[cmsx.machine.LDTU] = loadInst;
1658 instructions[cmsx.machine.LDOU] = loadInst;
1659 instructions[cmsx.machine.LDHT] = loadInst;
1660 instructions[cmsx.machine.LDSF] = loadInst;
1661
1662 StoreInstruction* storeInst = new StoreInstruction();
1663 instructionList.Add(UniquePtr<AssemblyInstruction>(storeInst));
1664 instructions[cmsx.machine.STB] = storeInst;
1665 instructions[cmsx.machine.STW] = storeInst;
1666 instructions[cmsx.machine.STT] = storeInst;
1667 instructions[cmsx.machine.STO] = storeInst;
1668 instructions[cmsx.machine.STBU] = storeInst;
1669 instructions[cmsx.machine.STWU] = storeInst;
1670 instructions[cmsx.machine.STTU] = storeInst;
1671 instructions[cmsx.machine.STOU] = storeInst;
1672 instructions[cmsx.machine.STHT] = storeInst;
1673 instructions[cmsx.machine.STSF] = storeInst;
1674
1675 StoreConstantInstruction* storeConstantInst = new StoreConstantInstruction();
1676 instructionList.Add(UniquePtr<AssemblyInstruction>(storeConstantInst));
1677 instructions[cmsx.machine.STCO] = storeConstantInst;
1678
1679 RegisterInstruction* registerInst = new RegisterInstruction();
1680 instructionList.Add(UniquePtr<AssemblyInstruction>(registerInst));
1681 instructions[cmsx.machine.ADD] = registerInst;
1682 instructions[cmsx.machine.SUB] = registerInst;
1683 instructions[cmsx.machine.MUL] = registerInst;
1684 instructions[cmsx.machine.DIV] = registerInst;
1685 instructions[cmsx.machine.ADDU] = registerInst;
1686 instructions[LDA] = registerInst;
1687 instructions[cmsx.machine.SUBU] = registerInst;
1688 instructions[cmsx.machine.MULU] = registerInst;
1689 instructions[cmsx.machine.DIVU] = registerInst;
1690 instructions[cmsx.machine.I2ADDU] = registerInst;
1691 instructions[cmsx.machine.I4ADDU] = registerInst;
1692 instructions[cmsx.machine.I8ADDU] = registerInst;
1693 instructions[cmsx.machine.I16ADDU] = registerInst;
1694 instructions[cmsx.machine.SL] = registerInst;
1695 instructions[cmsx.machine.SLU] = registerInst;
1696 instructions[cmsx.machine.SR] = registerInst;
1697 instructions[cmsx.machine.SRU] = registerInst;
1698 instructions[cmsx.machine.CMP] = registerInst;
1699 instructions[cmsx.machine.CMPU] = registerInst;
1700 instructions[cmsx.machine.CSN] = registerInst;
1701 instructions[cmsx.machine.CSZ] = registerInst;
1702 instructions[cmsx.machine.CSP] = registerInst;
1703 instructions[cmsx.machine.CSOD] = registerInst;
1704 instructions[cmsx.machine.CSNN] = registerInst;
1705 instructions[cmsx.machine.CSNZ] = registerInst;
1706 instructions[cmsx.machine.CSNP] = registerInst;
1707 instructions[cmsx.machine.CSEV] = registerInst;
1708 instructions[cmsx.machine.ZSN] = registerInst;
1709 instructions[cmsx.machine.ZSZ] = registerInst;
1710 instructions[cmsx.machine.ZSP] = registerInst;
1711 instructions[cmsx.machine.ZSOD] = registerInst;
1712 instructions[cmsx.machine.ZSNN] = registerInst;
1713 instructions[cmsx.machine.ZSNZ] = registerInst;
1714 instructions[cmsx.machine.ZSNP] = registerInst;
1715 instructions[cmsx.machine.ZSEV] = registerInst;
1716 instructions[cmsx.machine.AND] = registerInst;
1717 instructions[cmsx.machine.OR] = registerInst;
1718 instructions[cmsx.machine.XOR] = registerInst;
1719 instructions[cmsx.machine.ANDN] = registerInst;
1720 instructions[cmsx.machine.ORN] = registerInst;
1721 instructions[cmsx.machine.NAND] = registerInst;
1722 instructions[cmsx.machine.NOR] = registerInst;
1723 instructions[cmsx.machine.NXOR] = registerInst;
1724 instructions[cmsx.machine.MUX] = registerInst;
1725 instructions[cmsx.machine.SADD] = registerInst;
1726 instructions[cmsx.machine.BDIF] = registerInst;
1727 instructions[cmsx.machine.WDIF] = registerInst;
1728 instructions[cmsx.machine.TDIF] = registerInst;
1729 instructions[cmsx.machine.ODIF] = registerInst;
1730
1731 SetInstruction* setInst = new SetInstruction();
1732 instructionList.Add(UniquePtr<AssemblyInstruction>(setInst));
1733 instructions[SET] = setInst;
1734
1735 NegateInstruction* negInst = new NegateInstruction();
1736 instructionList.Add(UniquePtr<AssemblyInstruction>(negInst));
1737 instructions[cmsx.machine.NEG] = negInst;
1738 instructions[cmsx.machine.NEGU] = negInst;
1739
1740 FloatingPointInstruction* fpInst = new FloatingPointInstruction();
1741 instructionList.Add(UniquePtr<AssemblyInstruction>(fpInst));
1742 instructions[cmsx.machine.FADD] = fpInst;
1743 instructions[cmsx.machine.FSUB] = fpInst;
1744 instructions[cmsx.machine.FMUL] = fpInst;
1745 instructions[cmsx.machine.FDIV] = fpInst;
1746 instructions[cmsx.machine.FCMP] = fpInst;
1747
1748 FloatingRoundingInstruction* fprInst = new FloatingRoundingInstruction();
1749 instructionList.Add(UniquePtr<AssemblyInstruction>(fprInst));
1750 instructions[cmsx.machine.FINT] = fprInst;
1751 instructions[cmsx.machine.FIX] = fprInst;
1752 instructions[cmsx.machine.FIXU] = fprInst;
1753 instructions[cmsx.machine.FLOT] = fprInst;
1754 instructions[cmsx.machine.FLOTU] = fprInst;
1755 instructions[cmsx.machine.SFLOT] = fprInst;
1756 instructions[cmsx.machine.SFLOTU] = fprInst;
1757
1758
1759 WydeImmediateInstruction* wydeImmediateInst = new WydeImmediateInstruction();
1760 instructionList.Add(UniquePtr<AssemblyInstruction>(wydeImmediateInst));
1761 instructions[cmsx.machine.SETH] = wydeImmediateInst;
1762 instructions[cmsx.machine.SETMH] = wydeImmediateInst;
1763 instructions[cmsx.machine.SETML] = wydeImmediateInst;
1764 instructions[cmsx.machine.SETL] = wydeImmediateInst;
1765 instructions[cmsx.machine.INCH] = wydeImmediateInst;
1766 instructions[cmsx.machine.INCMH] = wydeImmediateInst;
1767 instructions[cmsx.machine.INCML] = wydeImmediateInst;
1768 instructions[cmsx.machine.INCL] = wydeImmediateInst;
1769 instructions[cmsx.machine.ORH] = wydeImmediateInst;
1770 instructions[cmsx.machine.ORMH] = wydeImmediateInst;
1771 instructions[cmsx.machine.ORML] = wydeImmediateInst;
1772 instructions[cmsx.machine.ORL] = wydeImmediateInst;
1773 instructions[cmsx.machine.ANDNH] = wydeImmediateInst;
1774 instructions[cmsx.machine.ANDNMH] = wydeImmediateInst;
1775 instructions[cmsx.machine.ANDNML] = wydeImmediateInst;
1776 instructions[cmsx.machine.ANDNL] = wydeImmediateInst;
1777
1778 JumpInstruction* jumpInst = new JumpInstruction();
1779 instructionList.Add(UniquePtr<AssemblyInstruction>(jumpInst));
1780 instructions[cmsx.machine.JMP] = jumpInst;
1781
1782 GoInstruction* goInst = new GoInstruction();
1783 instructionList.Add(UniquePtr<AssemblyInstruction>(goInst));
1784 instructions[cmsx.machine.GO] = goInst;
1785 CallInstruction* callInst = new CallInstruction();
1786 instructionList.Add(UniquePtr<AssemblyInstruction>(callInst));
1787 instructions[cmsx.machine.CALL] = callInst;
1788 RetInstruction* retInst = new RetInstruction();
1789 instructionList.Add(UniquePtr<AssemblyInstruction>(retInst));
1790 instructions[cmsx.machine.RET] = retInst;
1791 SwymInstruction* swymInst = new SwymInstruction();
1792 instructionList.Add(UniquePtr<AssemblyInstruction>(swymInst));
1793 instructions[cmsx.machine.SWYM] = swymInst;
1794
1795 BranchInstruction* branchInst = new BranchInstruction();
1796 instructionList.Add(UniquePtr<AssemblyInstruction>(branchInst));
1797 instructions[cmsx.machine.BN] = branchInst;
1798 instructions[cmsx.machine.BZ] = branchInst;
1799 instructions[cmsx.machine.BP] = branchInst;
1800 instructions[cmsx.machine.BOD] = branchInst;
1801 instructions[cmsx.machine.BNN] = branchInst;
1802 instructions[cmsx.machine.BNZ] = branchInst;
1803 instructions[cmsx.machine.BNP] = branchInst;
1804 instructions[cmsx.machine.BEV] = branchInst;
1805 instructions[cmsx.machine.PBN] = branchInst;
1806 instructions[cmsx.machine.PBZ] = branchInst;
1807 instructions[cmsx.machine.PBP] = branchInst;
1808 instructions[cmsx.machine.PBOD] = branchInst;
1809 instructions[cmsx.machine.PBNN] = branchInst;
1810 instructions[cmsx.machine.PBNZ] = branchInst;
1811 instructions[cmsx.machine.PBNP] = branchInst;
1812 instructions[cmsx.machine.PBEV] = branchInst;
1813
1814 TrapInstruction* trapInst = new TrapInstruction();
1815 instructionList.Add(UniquePtr<AssemblyInstruction>(trapInst));
1816 instructions[cmsx.machine.TRAP] = trapInst;
1817
1818 GetInstruction* getInst = new GetInstruction();
1819 instructionList.Add(UniquePtr<AssemblyInstruction>(getInst));
1820 instructions[cmsx.machine.GET] = getInst;
1821 PutInstruction* putInst = new PutInstruction();
1822 instructionList.Add(UniquePtr<AssemblyInstruction>(putInst));
1823 instructions[cmsx.machine.PUT] = putInst;
1824 }
1825 public AssemblyInstruction* GetAssemblyInstruction(int opcode, const Span& span) const
1826 {
1827 if (opcode >= 0 && opcode < instructions.Count())
1828 {
1829 return instructions[opcode];
1830 }
1831 else
1832 {
1833 Error("no assembly instruction for opcode " + ToString(opcode), span);
1834 return null;
1835 }
1836 }
1837 private static UniquePtr<AssemblyInstructionMap> instance;
1838 private List<UniquePtr<AssemblyInstruction>> instructionList;
1839 private List<AssemblyInstruction*> instructions;
1840 }
1841 }