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& assemblerInstruction* 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& assemblerInstruction* 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& assemblerInstruction* 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& assemblerInstruction* 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& assemblerInstruction* 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& assemblerInstruction* 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& assemblerInstruction* 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& assemblerInstruction* 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(sourceFileNamecast<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(functionSymbolIndexfunctionFullNamecast<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(offsetcast<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.valuecatchedTypeId2.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& assemblerInstruction* 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.register255unull));
 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.pure0unull));
 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& assemblerInstruction* 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.register255unull));
 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.register255unull)"X"y.symbol);
 560                                 assembler.EmitOpCode(opCode + 1u);
 561                                 assembler.EmitRegisterValue("X"x);
 562                                 assembler.EmitRegisterValue("Y"Value(Value.Flag.register255unull));
 563                                 assembler.EmitPureByteValue("Z"Value(Value.Flag.pure0unull));
 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& assemblerInstruction* 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.register255unull));
 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.register255unull)"X"y.symbol);
 648                                 assembler.EmitOpCode(opCode + 1u);
 649                                 assembler.EmitRegisterValue("X"x);
 650                                 assembler.EmitRegisterValue("Y"Value(Value.Flag.register255unull));
 651                                 assembler.EmitPureByteValue("Z"Value(Value.Flag.pure0unull));
 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& assemblerInstruction* 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.register255unull));
 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.pure0unull));
 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& assemblerInstruction* 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& assemblerInstruction* 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.pure0unull));
 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.pureb1null));
 817                             assembler.EmitPureByteValue("Z"Value(Value.Flag.pureb0null));
 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.pureb3null));
 832                             assembler.EmitPureByteValue("Z"Value(Value.Flag.pureb2null));
 833                             assembler.EmitOpCode(cmsx.machine.ORL);
 834                             assembler.EmitRegisterValue("X"x);
 835                             assembler.EmitPureByteValue("Y"Value(Value.Flag.pureb1null));
 836                             assembler.EmitPureByteValue("Z"Value(Value.Flag.pureb0null));
 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.pureb7null));
 859                             assembler.EmitPureByteValue("Z"Value(Value.Flag.pureb6null));
 860                             assembler.EmitOpCode(cmsx.machine.ORMH);
 861                             assembler.EmitRegisterValue("X"x);
 862                             assembler.EmitPureByteValue("Y"Value(Value.Flag.pureb5null));
 863                             assembler.EmitPureByteValue("Z"Value(Value.Flag.pureb4null));
 864                             assembler.EmitOpCode(cmsx.machine.ORML);
 865                             assembler.EmitRegisterValue("X"x);
 866                             assembler.EmitPureByteValue("Y"Value(Value.Flag.pureb3null));
 867                             assembler.EmitPureByteValue("Z"Value(Value.Flag.pureb2null));
 868                             assembler.EmitOpCode(cmsx.machine.ORL);
 869                             assembler.EmitRegisterValue("X"x);
 870                             assembler.EmitPureByteValue("Y"Value(Value.Flag.pureb1null));
 871                             assembler.EmitPureByteValue("Z"Value(Value.Flag.pureb0null));
 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& assemblerInstruction* 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.register255unull));
 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.pure0unull));
 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.pure0unull));
 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& assemblerInstruction* 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.pure1unull));
 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& assemblerInstruction* 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.pureb1null));
1045                         assembler.EmitPureByteValue("Z"Value(Value.Flag.pureb0null));
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& assemblerInstruction* 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& assemblerInstruction* 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.register255unull));
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.pure0unull));
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.pure0unull));
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& assemblerInstruction* 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.pure0unull));
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.pure0unull));
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& assemblerInstruction* 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.pure0unull));
1359                 assembler.EmitPureByteValue("Y"Value(Value.Flag.pure0unull));
1360                 assembler.EmitPureByteValue("Z"Value(Value.Flag.pure0unull));
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& assemblerInstruction* 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.pure0unull));
1383                 assembler.EmitPureByteValue("Y"Value(Value.Flag.pure0unull));
1384                 assembler.EmitPureByteValue("Z"Value(Value.Flag.pure0unull));
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& assemblerInstruction* 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"opCodexsymbol);
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& assemblerInstruction* 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& assemblerInstruction* 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.pure0unull));
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& assemblerInstruction* 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.pure0unull));
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& assemblerInstruction* 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& assemblerInstruction* 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 opcodeconst 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 }