1 using System;
2 using CodeFormatter = System.Text.CodeFormatter;
3
4 namespace cmsx.intermediate
5 {
6 public abstract class Register : Location
7 {
8 public nothrow Register(const string& name_) : name(name_)
9 {
10 }
11 public override void DebugPrint(CodeFormatter& formatter)
12 {
13 formatter << "reg." << name;
14 }
15 public override nothrow void Print(CodeFormatter& formatter)
16 {
17 formatter << name;
18 }
19 public override void GenerateLoad(int loadOpCode, Register* destinationReg, MachineCode& machineCode, Instruction* inst)
20 {
21 MachineInstruction* loadInstruction = machineCode.GetInstruction(loadOpCode, inst);
22 loadInstruction->AddOperand(destinationReg);
23 loadInstruction->AddOperand(this);
24 loadInstruction->AddOperand(machineCode.context.GetLiteralOperand(0u));
25 }
26 public override void GenerateLoadAddress(Register* destinationReg, MachineCode& machineCode, Instruction* inst)
27 {
28 MachineInstruction* setInstruction = machineCode.GetInstruction(cmsx.assembly.SET, inst);
29 setInstruction->AddOperand(destinationReg);
30 setInstruction->AddOperand(this);
31 }
32 public override void GenerateStore(int storeOpCode, Register* valueReg, MachineCode& machineCode, Instruction* inst)
33 {
34 MachineInstruction* storeInstruction = machineCode.GetInstruction(storeOpCode, inst);
35 storeInstruction->AddOperand(valueReg);
36 storeInstruction->AddOperand(this);
37 storeInstruction->AddOperand(machineCode.context.GetLiteralOperand(0u));
38 }
39 public string name;
40 }
41
42 public abstract class ParamRegister : Register
43 {
44 public nothrow ParamRegister(const string& name_) : base(name_)
45 {
46 }
47 }
48
49 public class Ix : Register
50 {
51 public nothrow Ix() : base("ix")
52 {
53 }
54 }
55
56 public class FP : Register
57 {
58 public nothrow FP() : base("fp")
59 {
60 }
61 }
62
63 public class SP : Register
64 {
65 public nothrow SP() : base("sp")
66 {
67 }
68 }
69
70 public class LocalRegister : Register
71 {
72 public nothrow LocalRegister(byte number_) : base("$" + ToString(number_)), number(number_)
73 {
74 }
75 public byte number;
76 }
77
78 public class Registers
79 {
80 public nothrow Registers()
81 {
82 paramRegisters.Add(ParamRegister("ax"));
83 paramRegisters.Add(ParamRegister("bx"));
84 paramRegisters.Add(ParamRegister("cx"));
85 paramRegisters.Add(ParamRegister("dx"));
86 paramRegisters.Add(ParamRegister("ex"));
87 byte n = Flags.NumLocalRegs();
88 for (byte i = 0u; i < n; ++i;)
89 {
90 localRegisters.Add(LocalRegister(i));
91 }
92 }
93 public inline nothrow byte GetNumParamRegisters() const
94 {
95 return cast<byte>(paramRegisters.Count());
96 }
97 public inline nothrow ParamRegister* GetParamRegister(byte index) const
98 {
99 return ¶mRegisters[index];
100 }
101 public inline nothrow byte GetNumLocalRegisters() const
102 {
103 return cast<byte>(localRegisters.Count());
104 }
105 public LocalRegister* GetLocalRegister(byte index)
106 {
107 if (index >= localRegisters.Count())
108 {
109 throw Exception("number of local registers (" + ToString(localRegisters.Count()) + ") exceeded");
110 }
111 return &localRegisters[index];
112 }
113 public inline nothrow Ix* GetIx()
114 {
115 return &ix;
116 }
117 public inline nothrow FP* GetFP()
118 {
119 return &fp;
120 }
121 public inline nothrow SP* GetSP()
122 {
123 return &sp;
124 }
125 private List<ParamRegister> paramRegisters;
126 private List<LocalRegister> localRegisters;
127 private Ix ix;
128 private FP fp;
129 private SP sp;
130 }
131 }
132