1 using System;
   2 using System.Collections;
   3 
   4 namespace cmsx.intermediate
   5 {
   6     public abstract class Value
   7     {
   8         public default nothrow Value();
   9         public virtual default ~Value();
  10         public abstract nothrow string Name() const;
  11         public virtual nothrow string PrintName() const
  12         {
  13             return Name();
  14         }
  15         public virtual nothrow string IndexStr() const
  16         {
  17             return Name();
  18         }
  19         public virtual nothrow Location* HomeLocation() const
  20         {
  21             return null;
  22         }
  23         public virtual nothrow bool IsImmediate(byte& immediateValue) const
  24         {
  25             return false;
  26         }
  27         public virtual void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
  28         {
  29             throw Exception("error: tried to generate set for '" + string(type->Name()) + "' value (line " + ToString(line) + ")");
  30         }
  31         public virtual Value* SignExtendTo(Type* targetTypeint line)
  32         {
  33             throw Exception("error: tried to sign extend '" + type->Name() + "' type value to '" + targetType->Name() + " type value (line " + ToString(line) + ")");
  34         }
  35         public virtual Value* ZeroExtendTo(Type* targetTypeint line)
  36         {
  37             throw Exception("error: tried to zero extend '" + type->Name() + "' type value to '" + targetType->Name() + " type value (line " + ToString(line) + ")");
  38         }
  39         public virtual Value* TruncateTo(Type* targetTypeint line)
  40         {
  41             throw Exception("error: tried to truncate '" + type->Name() + "' type value to '" + targetType->Name() + " type value (line " + ToString(line) + ")");
  42         }
  43         public virtual void Validate(Type* typeconst string& index)
  44         {
  45             Type* thisType = this->type;
  46             if (thisType != type)
  47             {
  48                 throw Exception("error: type conflict: element " + index + " has type '" + thisType->Name() + "', type '" + type->Name() + "' expected");
  49             }
  50         }
  51         public virtual nothrow void IncNumUses()
  52         {
  53         }
  54         public Type* type;
  55         public int line;
  56     }
  57 
  58     public class ConstantValue : Value
  59     {
  60         public override nothrow string Name() const
  61         {
  62             return "constant";
  63         }
  64         public virtual void GenerateCode(MachineCode& machineCodestring& labelContext& context)
  65         {
  66             throw Exception("error: tried to generate code for " + string(typename(*this)));
  67         }
  68         public virtual Operand* MakeDataOperand(Context& context) const
  69         {
  70             throw Exception("error: tried to make data operand for " + string(typename(*this)));
  71         }
  72     }
  73 
  74     public class LiteralValue : ConstantValue
  75     {
  76         public override nothrow string Name() const
  77         {
  78             return "literal";
  79         }
  80     }
  81 
  82     public class BoolValue : LiteralValue
  83     {
  84         public default nothrow BoolValue();
  85         public nothrow BoolValue(bool value_) : value(value_)
  86         {
  87         }
  88         public override nothrow string Name() const
  89         {
  90             return ToString(value);
  91         }
  92         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
  93         {
  94             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
  95             setInst->AddOperand(reg);
  96             setInst->AddOperand(machineCode.context.GetLiteralOperand(cast<ulong>(value)));
  97         }
  98         public override ConstantValue* SignExtendTo(Type* targetTypeint line)
  99         {
 100             return targetType->MakeValue(cmsx.util.SignExtend(cast<byte>(value)));
 101         }
 102         public override ConstantValue* ZeroExtendTo(Type* targetTypeint line)
 103         {
 104             return targetType->MakeValue(cast<ulong>(value));
 105         }
 106         public override ConstantValue* TruncateTo(Type* targetTypeint line)
 107         {
 108             return targetType->MakeValue(cast<ulong>(value));
 109         }
 110         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 111         {
 112             MachineInstruction* byteInst = machineCode.GetInstruction(cmsx.assembly.BYTElabel);
 113             byteInst->AddOperand(MakeDataOperand(context));
 114             label.Clear();
 115         }
 116         public override Operand* MakeDataOperand(Context& context) const
 117         {
 118             return context.GetLiteralOperand(cast<byte>(value));
 119         }
 120         public bool value;
 121     }
 122 
 123     public class SByteValue : LiteralValue
 124     {
 125         public default nothrow SByteValue();
 126         public nothrow SByteValue(sbyte value_) : value(value_)
 127         {
 128         }
 129         public override nothrow string Name() const
 130         {
 131             return ToString(value);
 132         }
 133         public override nothrow bool IsImmediate(byte& immediateValue) const
 134         {
 135             if (value >= 0)
 136             {
 137                 immediateValue = cast<byte>(value);
 138                 return true;
 139             }
 140             else
 141             {
 142                 return false;
 143             }
 144         }
 145         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 146         {
 147             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 148             setInst->AddOperand(reg);
 149             setInst->AddOperand(machineCode.context.GetLiteralOperand(cast<byte>(value)));
 150         }
 151         public override ConstantValue* SignExtendTo(Type* targetTypeint line)
 152         {
 153             return targetType->MakeValue(cmsx.util.SignExtend(cast<byte>(value)));
 154         }
 155         public override ConstantValue* TruncateTo(Type* targetTypeint line)
 156         {
 157             return targetType->MakeValue(cast<ulong>(value));
 158         }
 159         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 160         {
 161             MachineInstruction* byteInst = machineCode.GetInstruction(cmsx.assembly.BYTElabel);
 162             byteInst->AddOperand(MakeDataOperand(context));
 163             label.Clear();
 164         }
 165         public override Operand* MakeDataOperand(Context& context) const
 166         {
 167             return context.GetLiteralOperand(cast<byte>(value));
 168         }
 169         public sbyte value;
 170     }
 171 
 172     public class ByteValue : LiteralValue
 173     {
 174         public default nothrow ByteValue();
 175         public nothrow ByteValue(byte value_) : value(value_)
 176         {
 177         }
 178         public override nothrow string Name() const
 179         {
 180             return ToString(value);
 181         }
 182         public override nothrow bool IsImmediate(byte& immediateValue) const
 183         {
 184             immediateValue = value;
 185             return true;
 186         }
 187         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 188         {
 189             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 190             setInst->AddOperand(reg);
 191             setInst->AddOperand(machineCode.context.GetLiteralOperand(value));
 192         }
 193         public override ConstantValue* SignExtendTo(Type* targetTypeint line)
 194         {
 195             return targetType->MakeValue(cmsx.util.SignExtend(value));
 196         }
 197         public override ConstantValue* ZeroExtendTo(Type* targetTypeint line)
 198         {
 199             return targetType->MakeValue(value);
 200         }
 201         public override ConstantValue* TruncateTo(Type* targetTypeint line)
 202         {
 203             return targetType->MakeValue(cast<ulong>(value));
 204         }
 205         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 206         {
 207             MachineInstruction* byteInst = machineCode.GetInstruction(cmsx.assembly.BYTElabel);
 208             byteInst->AddOperand(MakeDataOperand(context));
 209             label.Clear();
 210         }
 211         public override Operand* MakeDataOperand(Context& context) const
 212         {
 213             return context.GetLiteralOperand(value);
 214         }
 215         public byte value;
 216     }
 217 
 218     public class ShortValue : LiteralValue
 219     {
 220         public default nothrow ShortValue();
 221         public nothrow ShortValue(short value_) : value(value_)
 222         {
 223         }
 224         public override nothrow string Name() const
 225         {
 226             return ToString(value);
 227         }
 228         public override nothrow bool IsImmediate(byte& immediateValue) const
 229         {
 230             if (value >= 0 && value <= 255)
 231             {
 232                 immediateValue = cast<byte>(value);
 233                 return true;
 234             }
 235             else
 236             {
 237                 return false;
 238             }
 239         }
 240         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 241         {
 242             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 243             setInst->AddOperand(reg);
 244             setInst->AddOperand(machineCode.context.GetLiteralOperand(cast<ushort>(value)));
 245         }
 246         public override ConstantValue* SignExtendTo(Type* targetTypeint line)
 247         {
 248             return targetType->MakeValue(cmsx.util.SignExtend(cast<ushort>(value)));
 249         }
 250         public override ConstantValue* TruncateTo(Type* targetTypeint line)
 251         {
 252             return targetType->MakeValue(cast<ulong>(value));
 253         }
 254         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 255         {
 256             MachineInstruction* wydeInst = machineCode.GetInstruction(cmsx.assembly.WYDElabel);
 257             wydeInst->AddOperand(MakeDataOperand(context));
 258             label.Clear();
 259         }
 260         public override Operand* MakeDataOperand(Context& context) const
 261         {
 262             return context.GetLiteralOperand(cast<ushort>(value));
 263         }
 264         public short value;
 265     }
 266 
 267     public class UShortValue : LiteralValue
 268     {
 269         public default nothrow UShortValue();
 270         public nothrow UShortValue(ushort value_) : value(value_)
 271         {
 272         }
 273         public override nothrow string Name() const
 274         {
 275             return ToString(value);
 276         }
 277         public override nothrow bool IsImmediate(byte& immediateValue) const
 278         {
 279             if (value <= 255u)
 280             {
 281                 immediateValue = cast<byte>(value);
 282                 return true;
 283             }
 284             else
 285             {
 286                 return false;
 287             }
 288         }
 289         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 290         {
 291             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 292             setInst->AddOperand(reg);
 293             setInst->AddOperand(machineCode.context.GetLiteralOperand(value));
 294         }
 295         public override ConstantValue* SignExtendTo(Type* targetTypeint line)
 296         {
 297             return targetType->MakeValue(cmsx.util.SignExtend(value));
 298         }
 299         public override ConstantValue* ZeroExtendTo(Type* targetTypeint line)
 300         {
 301             return targetType->MakeValue(value);
 302         }
 303         public override ConstantValue* TruncateTo(Type* targetTypeint line)
 304         {
 305             return targetType->MakeValue(cast<ulong>(value));
 306         }
 307         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 308         {
 309             MachineInstruction* wydeInst = machineCode.GetInstruction(cmsx.assembly.WYDElabel);
 310             wydeInst->AddOperand(MakeDataOperand(context));
 311             label.Clear();
 312         }
 313         public override Operand* MakeDataOperand(Context& context) const
 314         {
 315             return context.GetLiteralOperand(value);
 316         }
 317         public ushort value;
 318     }
 319 
 320     public class IntValue : LiteralValue
 321     {
 322         public default nothrow IntValue();
 323         public nothrow IntValue(int value_) : value(value_)
 324         {
 325         }
 326         public override nothrow string Name() const
 327         {
 328             return ToString(value);
 329         }
 330         public override nothrow bool IsImmediate(byte& immediateValue) const
 331         {
 332             if (value >= 0 && value <= 255)
 333             {
 334                 immediateValue = cast<byte>(value);
 335                 return true;
 336             }
 337             else
 338             {
 339                 return false;
 340             }
 341         }
 342         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 343         {
 344             ushort low = cast<ushort>(value);
 345             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 346             setInst->AddOperand(reg);
 347             setInst->AddOperand(machineCode.context.GetLiteralOperand(low));
 348             ushort high = cast<ushort>(value >> 16);
 349             if (high != 0u)
 350             {
 351                 MachineInstruction* orMLInst =  machineCode.GetInstruction(cmsx.machine.ORMLinst);
 352                 orMLInst->AddOperand(reg);
 353                 orMLInst->AddOperand(machineCode.context.GetLiteralOperand(high));
 354             }
 355         }
 356         public override ConstantValue* SignExtendTo(Type* targetTypeint line)
 357         {
 358             return targetType->MakeValue(cmsx.util.SignExtend(cast<uint>(value)));
 359         }
 360         public override ConstantValue* TruncateTo(Type* targetTypeint line)
 361         {
 362             return targetType->MakeValue(cast<ulong>(value));
 363         }
 364         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 365         {
 366             MachineInstruction* tetraInst = machineCode.GetInstruction(cmsx.assembly.TETRAlabel);
 367             tetraInst->AddOperand(MakeDataOperand(context));
 368             label.Clear();
 369         }
 370         public override Operand* MakeDataOperand(Context& context) const
 371         {
 372             return context.GetLiteralOperand(cast<uint>(value));
 373         }
 374         public int value;
 375     }
 376 
 377     public class UIntValue : LiteralValue
 378     {
 379         public default nothrow UIntValue();
 380         public nothrow UIntValue(uint value_) : value(value_)
 381         {
 382         }
 383         public override nothrow string Name() const
 384         {
 385             return ToString(value);
 386         }
 387         public override nothrow bool IsImmediate(byte& immediateValue) const
 388         {
 389             if (value <= 255u)
 390             {
 391                 immediateValue = cast<byte>(value);
 392                 return true;
 393             }
 394             else
 395             {
 396                 return false;
 397             }
 398         }
 399         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 400         {
 401             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 402             setInst->AddOperand(reg);
 403             ushort low = cast<ushort>(value);
 404             setInst->AddOperand(machineCode.context.GetLiteralOperand(low));
 405             ushort high = cast<ushort>(value >> 16u);
 406             if (high != 0u)
 407             {
 408                 MachineInstruction* orMLInst =  machineCode.GetInstruction(cmsx.machine.ORMLinst);
 409                 orMLInst->AddOperand(reg);
 410                 orMLInst->AddOperand(machineCode.context.GetLiteralOperand(high));
 411             }
 412         }
 413         public override ConstantValue* SignExtendTo(Type* targetTypeint line)
 414         {
 415             return targetType->MakeValue(cmsx.util.SignExtend(value));
 416         }
 417         public override ConstantValue* ZeroExtendTo(Type* targetTypeint line)
 418         {
 419             return targetType->MakeValue(value);
 420         }
 421         public override ConstantValue* TruncateTo(Type* targetTypeint line)
 422         {
 423             return targetType->MakeValue(cast<ulong>(value));
 424         }
 425         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 426         {
 427             MachineInstruction* tetraInst = machineCode.GetInstruction(cmsx.assembly.TETRAlabel);
 428             tetraInst->AddOperand(MakeDataOperand(context));
 429             label.Clear();
 430         }
 431         public override Operand* MakeDataOperand(Context& context) const
 432         {
 433             return context.GetLiteralOperand(value);
 434         }
 435         public uint value;
 436     }
 437 
 438     public class LongValue : LiteralValue
 439     {
 440         public default nothrow LongValue();
 441         public nothrow LongValue(long value_) : value(value_)
 442         {
 443         }
 444         public override nothrow string Name() const
 445         {
 446             return ToString(value);
 447         }
 448         public override nothrow bool IsImmediate(byte& immediateValue) const
 449         {
 450             if (value >= 0 && value <= 255)
 451             {
 452                 immediateValue = cast<byte>(value);
 453                 return true;
 454             }
 455             else
 456             {
 457                 return false;
 458             }
 459         }
 460         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 461         {
 462             ushort low = cast<ushort>(value);
 463             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 464             setInst->AddOperand(reg);
 465             setInst->AddOperand(machineCode.context.GetLiteralOperand(low));
 466             ushort ml = cast<ushort>(value >> 16u);
 467             if (ml != 0u)
 468             {
 469                 MachineInstruction* orMLInst =  machineCode.GetInstruction(cmsx.machine.ORMLinst);
 470                 orMLInst->AddOperand(reg);
 471                 orMLInst->AddOperand(machineCode.context.GetLiteralOperand(ml));
 472             }
 473             ushort mh = cast<ushort>(value >> 32u);
 474             if (mh != 0u)
 475             {
 476                 MachineInstruction* orMHInst =  machineCode.GetInstruction(cmsx.machine.ORMHinst);
 477                 orMHInst->AddOperand(reg);
 478                 orMHInst->AddOperand(machineCode.context.GetLiteralOperand(mh));
 479             }
 480             ushort h = cast<ushort>(value >> 48u);
 481             if (h != 0u)
 482             {
 483                 MachineInstruction* orHInst =  machineCode.GetInstruction(cmsx.machine.ORHinst);
 484                 orHInst->AddOperand(reg);
 485                 orHInst->AddOperand(machineCode.context.GetLiteralOperand(h));
 486             }
 487         }
 488         public override ConstantValue* SignExtendTo(Type* targetTypeint line)
 489         {
 490             return targetType->MakeValue(cast<ulong>(value));
 491         }
 492         public override ConstantValue* TruncateTo(Type* targetTypeint line)
 493         {
 494             return targetType->MakeValue(cast<ulong>(value));
 495         }
 496         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 497         {
 498             MachineInstruction* octaInst = machineCode.GetInstruction(cmsx.assembly.OCTAlabel);
 499             octaInst->AddOperand(MakeDataOperand(context));
 500             label.Clear();
 501         }
 502         public override Operand* MakeDataOperand(Context& context) const
 503         {
 504             return context.GetLiteralOperand(cast<ulong>(value));
 505         }
 506         public long value;
 507     }
 508 
 509     public class ULongValue : LiteralValue
 510     {
 511         public default nothrow ULongValue();
 512         public nothrow ULongValue(ulong value_) : value(value_)
 513         {
 514         }
 515         public override nothrow string Name() const
 516         {
 517             return ToString(value);
 518         }
 519         public override nothrow bool IsImmediate(byte& immediateValue) const
 520         {
 521             if (value <= 255u)
 522             {
 523                 immediateValue = cast<byte>(value);
 524                 return true;
 525             }
 526             else
 527             {
 528                 return false;
 529             }
 530         }
 531         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 532         {
 533             ushort low = cast<ushort>(value);
 534             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 535             setInst->AddOperand(reg);
 536             setInst->AddOperand(machineCode.context.GetLiteralOperand(low));
 537             ushort ml = cast<ushort>(value >> 16u);
 538             if (ml != 0)
 539             {
 540                 MachineInstruction* orMLInst =  machineCode.GetInstruction(cmsx.machine.ORMLinst);
 541                 orMLInst->AddOperand(reg);
 542                 orMLInst->AddOperand(machineCode.context.GetLiteralOperand(ml));
 543             }
 544             ushort mh = cast<ushort>(value >> 32u);
 545             if (mh != 0u)
 546             {
 547                 MachineInstruction* orMHInst =  machineCode.GetInstruction(cmsx.machine.ORMHinst);
 548                 orMHInst->AddOperand(reg);
 549                 orMHInst->AddOperand(machineCode.context.GetLiteralOperand(mh));
 550             }
 551             ushort h = cast<ushort>(value >> 48u);
 552             if (h != 0u)
 553             {
 554                 MachineInstruction* orHInst =  machineCode.GetInstruction(cmsx.machine.ORHinst);
 555                 orHInst->AddOperand(reg);
 556                 orHInst->AddOperand(machineCode.context.GetLiteralOperand(h));
 557             }
 558         }
 559         public override ConstantValue* SignExtendTo(Type* targetTypeint line)
 560         {
 561             return targetType->MakeValue(value);
 562         }
 563         public override ConstantValue* ZeroExtendTo(Type* targetTypeint line)
 564         {
 565             return targetType->MakeValue(value);
 566         }
 567         public override ConstantValue* TruncateTo(Type* targetTypeint line)
 568         {
 569             return targetType->MakeValue(value);
 570         }
 571         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 572         {
 573             MachineInstruction* octaInst = machineCode.GetInstruction(cmsx.assembly.OCTAlabel);
 574             octaInst->AddOperand(MakeDataOperand(context));
 575             label.Clear();
 576         }
 577         public override Operand* MakeDataOperand(Context& context) const
 578         {
 579             return context.GetLiteralOperand(value);
 580         }
 581         public ulong value;
 582     }
 583 
 584     public class FloatValue : LiteralValue
 585     {
 586         public default nothrow FloatValue();
 587         public nothrow FloatValue(float value_) : value(value_)
 588         {
 589         }
 590         public override nothrow string Name() const
 591         {
 592             return ToString(value115);
 593         }
 594         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 595         {
 596             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 597             setInst->AddOperand(reg);
 598             uint x = *cast<uint*>(cast<void*>(&value));
 599             ushort low = cast<ushort>(x);
 600             setInst->AddOperand(machineCode.context.GetLiteralOperand(low));
 601             ushort ml = cast<ushort>(x >> 16u);
 602             if (ml != 0)
 603             {
 604                 MachineInstruction* orMLInst =  machineCode.GetInstruction(cmsx.machine.ORMLinst);
 605                 orMLInst->AddOperand(reg);
 606                 orMLInst->AddOperand(machineCode.context.GetLiteralOperand(ml));
 607             }
 608         }
 609         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 610         {
 611             MachineInstruction* tetraInst = machineCode.GetInstruction(cmsx.assembly.TETRAlabel);
 612             tetraInst->AddOperand(MakeDataOperand(context));
 613             label.Clear();
 614         }
 615         public override Operand* MakeDataOperand(Context& context) const
 616         {
 617             return context.GetLiteralOperand(*cast<uint*>(cast<void*>(&value)));
 618         }
 619         public float value;
 620     }
 621 
 622     public class DoubleValue : LiteralValue
 623     {
 624         public default nothrow DoubleValue();
 625         public nothrow DoubleValue(double value_) : value(value_)
 626         {
 627         }
 628         public override nothrow string Name() const
 629         {
 630             return ToString(value115);
 631         }
 632         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 633         {
 634             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 635             setInst->AddOperand(reg);
 636             ulong x = *cast<ulong*>(cast<void*>(&value));
 637             ushort low = cast<ushort>(x);
 638             setInst->AddOperand(machineCode.context.GetLiteralOperand(low));
 639             ushort ml = cast<ushort>(x >> 16u);
 640             if (ml != 0)
 641             {
 642                 MachineInstruction* orMLInst =  machineCode.GetInstruction(cmsx.machine.ORMLinst);
 643                 orMLInst->AddOperand(reg);
 644                 orMLInst->AddOperand(machineCode.context.GetLiteralOperand(ml));
 645             }
 646             ushort mh = cast<ushort>(x >> 32u);
 647             if (mh != 0u)
 648             {
 649                 MachineInstruction* orMHInst =  machineCode.GetInstruction(cmsx.machine.ORMHinst);
 650                 orMHInst->AddOperand(reg);
 651                 orMHInst->AddOperand(machineCode.context.GetLiteralOperand(mh));
 652             }
 653             ushort h = cast<ushort>(x >> 48u);
 654             if (h != 0u)
 655             {
 656                 MachineInstruction* orHInst =  machineCode.GetInstruction(cmsx.machine.ORHinst);
 657                 orHInst->AddOperand(reg);
 658                 orHInst->AddOperand(machineCode.context.GetLiteralOperand(h));
 659             }
 660         }
 661         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 662         {
 663             MachineInstruction* octaInst = machineCode.GetInstruction(cmsx.assembly.OCTAlabel);
 664             octaInst->AddOperand(MakeDataOperand(context));
 665             label.Clear();
 666         }
 667         public override Operand* MakeDataOperand(Context& context) const
 668         {
 669             return context.GetLiteralOperand(*cast<ulong*>(cast<void*>(&value)));
 670         }
 671         public double value;
 672     }
 673 
 674     public class NullValue : LiteralValue
 675     {
 676         public nothrow NullValue(PtrType* ptrType_) : ptrType(ptrType_)
 677         {
 678             type = ptrType;
 679         }
 680         public override nothrow string Name() const
 681         {
 682             return "null";
 683         }
 684         public override void GenerateSetValue(Register* regMachineCode& machineCodeint lineInstruction* inst)
 685         {
 686             MachineInstruction* setInst = machineCode.GetInstruction(cmsx.assembly.SETinst);
 687             setInst->AddOperand(reg);
 688             setInst->AddOperand(machineCode.context.GetLiteralOperand(0u));
 689         }
 690         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 691         {
 692             MachineInstruction* octaInst = machineCode.GetInstruction(cmsx.assembly.OCTAlabel);
 693             octaInst->AddOperand(MakeDataOperand(context));
 694             label.Clear();
 695         }
 696         public override Operand* MakeDataOperand(Context& context) const
 697         {
 698             return context.GetLiteralOperand(0u);
 699         }
 700         public PtrType* ptrType;
 701     }
 702 
 703     public class PtrValue : ConstantValue
 704     {
 705         public nothrow PtrValue(PtrType* ptrType_GlobalVariable* globalVariable_) : globalVariable(globalVariable_)
 706         {
 707             type = ptrType_;
 708         }
 709         public override nothrow string Name() const
 710         {
 711             return globalVariable->Name();
 712         }
 713         public override nothrow Location* HomeLocation() const
 714         {
 715             return globalVariable->HomeLocation();
 716         }
 717         public override Operand* MakeDataOperand(Context& context) const
 718         {
 719             return context.GetSymbolOperand(globalVariable->name);
 720         }
 721         public GlobalVariable* globalVariable;
 722     }
 723 
 724     public abstract class AggregateValue : ConstantValue
 725     {
 726     }
 727 
 728     public class ArrayValue : AggregateValue
 729     {
 730         public nothrow ArrayValue()
 731         {
 732         }
 733         public void AddElement(ConstantValue* element)
 734         {
 735             elements.Add(element);
 736         }
 737         public override void Validate(Type* typeconst string& index)
 738         {
 739             if (!(type is ArrayType*))
 740             {
 741                 throw Exception("error: element " + index + " not an array value ('" + type->Name() + "')");
 742             }
 743             ArrayType* arrayType = cast<ArrayType*>(type);
 744             if (arrayType->ElementCount() != elements.Count())
 745             {
 746                 throw Exception("error: element " + index + " has " + ToString(elements.Count()) + " elements, " + ToString(arrayType->ElementCount()) + " elements expected");
 747             }
 748             this->type = arrayType;
 749             int i = 0;
 750             for (ConstantValue* element : elements)
 751             {
 752                 element->Validate(arrayType->ElementType()index + "." + ToString(i));
 753                 ++i;
 754             }
 755         }
 756         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 757         {
 758             ArrayType* arrayType = cast<ArrayType*>(type);
 759             MachineInstruction* inst = arrayType->ElementType()->GetDataInstruction(machineCodeline);
 760             inst->SetLabel(label);
 761             for (ConstantValue* element : elements)
 762             {
 763                 inst->AddOperand(element->MakeDataOperand(context));
 764             }
 765             label.Clear();
 766         }
 767         public override nothrow string Name() const
 768         {
 769             string name = "[ ";
 770             bool first = true;
 771             for (ConstantValue* element : elements)
 772             {
 773                 if (first)
 774                 {
 775                     first = false;
 776                 }
 777                 else
 778                 {
 779                     name.Append(", ");
 780                 }
 781                 if (element is AggregateValue*)
 782                 {
 783                     name.Append(element->Name());
 784                 }
 785                 else
 786                 {
 787                     name.Append(element->type->Name()).Append(' ').Append(element->Name());
 788                 }
 789             }
 790             name.Append(" ]");
 791             return name;
 792         }
 793         public List<ConstantValue*> elements;
 794     }
 795 
 796     public class StructureValue : AggregateValue
 797     {
 798         public nothrow StructureValue()
 799         {
 800         }
 801         public void AddMember(ConstantValue* member)
 802         {
 803             members.Add(member);
 804         }
 805         public override void Validate(Type* typeconst string& index)
 806         {
 807             if (!(type is StructureType*))
 808             {
 809                 throw Exception("error: element " + index + " is not a structure value ('" + type->Name() + "')");
 810             }
 811             StructureType* structureType = cast<StructureType*>(type);
 812             if (structureType->memberTypes.Count() != members.Count())
 813             {
 814                 throw Exception("error: element " + index + " has " + ToString(members.Count()) + " members, " + ToString(structureType->memberTypes.Count()) + " members expected");
 815             }
 816             this->type = structureType;
 817             long n = members.Count();
 818             for (long i = 0; i < n; ++i;)
 819             {
 820                 members[i]->Validate(structureType->memberTypes[i]index + "." + ToString(i));
 821             }
 822         }
 823         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 824         {
 825             for (ConstantValue* member : members)
 826             {
 827                 member->GenerateCode(machineCodelabelcontext);
 828             }
 829         }
 830         public override nothrow string Name() const
 831         {
 832             string name = "{ ";
 833             bool first = true;
 834             for (ConstantValue* member : members)
 835             {
 836                 if (first)
 837                 {
 838                     first = false;
 839                 }
 840                 else
 841                 {
 842                     name.Append(", ");
 843                 }
 844                 if (member is AggregateValue*)
 845                 {
 846                     name.Append(member->Name());
 847                 }
 848                 else
 849                 {
 850                     name.Append(member->type->Name()).Append(' ').Append(member->Name());
 851                 }
 852             }
 853             name.Append(" }");
 854             return name;
 855         }
 856         public List<ConstantValue*> members;
 857     }
 858 
 859     public class StringValue : ConstantValue
 860     {
 861         public nothrow StringValue(const string& value_) : base()value(value_)
 862         {
 863         }
 864         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 865         {
 866             MachineInstruction* inst = machineCode.GetInstruction(cmsx.assembly.BYTElabel);
 867             int state = 0;
 868             string str;
 869             string hex;
 870             for (char c : value)
 871             {
 872                 switch (state)
 873                 {
 874                     case 0:
 875                     {
 876                         if (c == '\\')
 877                         {
 878                             if (!str.IsEmpty())
 879                             {
 880                                 inst->AddOperand(context.GetStringOperand(str));
 881                                 str.Clear();
 882                             }
 883                             hex.Clear();
 884                             state = 1;
 885                         }
 886                         else
 887                         {
 888                             str.Append(c);
 889                         }
 890                         break;
 891                     }
 892                     case 1:
 893                     {
 894                         hex.Append(c);
 895                         state = 2;
 896                         break;
 897                     }
 898                     case 2:
 899                     {
 900                         hex.Append(c);
 901                         inst->AddOperand(context.GetLiteralOperand(ParseHexByte(hex)));
 902                         hex.Clear();
 903                         state = 0;
 904                         break;
 905                     }
 906                 }
 907             }
 908             if (state == 0)
 909             {
 910                 if (!str.IsEmpty())
 911                 {
 912                     inst->AddOperand(context.GetStringOperand(str));
 913                 }
 914             }
 915             else if (state == 1)
 916             {
 917                 throw Exception("two hex characters expected (line=" + ToString(line) + ")");
 918             }
 919             else if (state == 2)
 920             {
 921                 throw Exception("one hex character expected (line=" + ToString(line) + ")");
 922             }
 923         }
 924         public override nothrow string Name() const
 925         {
 926             string name = "\"";
 927             name.Append(value);
 928             name.Append("\"");
 929             return name;
 930         }
 931         public string value;
 932     }
 933 
 934     public class StringArrayValue : ArrayValue
 935     {
 936         public nothrow StringArrayValue(char prefix_) : base()prefix(prefix_)
 937         {
 938         }
 939         public override void Validate(Type* typeconst string& index)
 940         {
 941             if (this->type != type)
 942             {
 943                 Type* thisType = this->type;
 944                 throw Exception("error: type conflict: element " + index + " has type '" + thisType->Name() + "', type '" + type->Name() + "' expected");
 945             }
 946             int i = 0;
 947             for (ConstantValue* element : elements)
 948             {
 949                 element->Validate(typeindex + "." + ToString(i));
 950                 ++i;
 951             }
 952         }
 953         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 954         {
 955             MachineInstruction* inst = type->GetDataInstruction(machineCodeline);
 956             inst->SetLabel(label);
 957             for (ConstantValue* element : elements)
 958             {
 959                 inst->AddOperand(element->MakeDataOperand(context));
 960             }
 961             label.Clear();
 962         }
 963         public override nothrow string Name() const
 964         {
 965             string name = ToString(prefix) + base->Name();
 966             return name;
 967         }
 968         private char prefix;
 969     }
 970 
 971     public class ConversionValue : ConstantValue
 972     {
 973         public nothrow ConversionValue(Type* targetType_ConstantValue* from_) : base()from(from_)
 974         {
 975             type = targetType_;
 976         }
 977         public override nothrow string Name() const
 978         {
 979             return "conv(" + from->type->Name() + " " + from->Name() + ")";
 980         }
 981         public override Operand* MakeDataOperand(Context& context) const
 982         {
 983             return from->MakeDataOperand(context);
 984         }
 985         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
 986         {
 987             MachineInstruction* inst = type->GetDataInstruction(machineCodeline);
 988             inst->AddOperand(from->MakeDataOperand(context));
 989         }
 990         private ConstantValue* from;
 991     }
 992 
 993     public class IdValue : Value
 994     {
 995         public IdValue(uint id_) : base()id(id_)
 996         {
 997         }
 998         public override nothrow string Name() const
 999         {
1000             return "$" + ToString(id);
1001         }
1002         public uint id;
1003     }
1004 
1005     public class SymbolValue : ConstantValue
1006     {
1007         public nothrow SymbolValue(const string& symbol_) : base()symbol(symbol_)
1008         {
1009         }
1010         public override nothrow string Name() const
1011         {
1012             return symbol;
1013         }
1014         public override nothrow string PrintName() const
1015         {
1016             return "@" + Name();
1017         }
1018         public override Operand* MakeDataOperand(Context& context) const
1019         {
1020             return context.GetSymbolOperand(symbol);
1021         }
1022         public override void GenerateCode(MachineCode& machineCodestring& labelContext& context)
1023         {
1024             MachineInstruction* inst = machineCode.GetInstruction(cmsx.assembly.OCTAlabel);
1025             inst->AddOperand(MakeDataOperand(context));
1026         }
1027         public string symbol;
1028     }
1029 
1030     public class ClsIdValue : ConstantValue
1031     {
1032         public ClsIdValue(const string& typeId_) : base()typeId(typeId_)
1033         {
1034         }
1035         public override nothrow string Name() const
1036         {
1037             return "$CLSID(" + typeId + ")";
1038         }
1039         public override Operand* MakeDataOperand(Context& context) const
1040         {
1041             return context.GetClsIdOperand(typeId);
1042         }
1043         private string typeId;
1044     }
1045 }