@@ -23,7 +23,11 @@ type RV64_InstrKind enum u8 {
2323 Add,
2424 AddIw,
2525 And,
26+ Beqz,
27+ Bnez,
2628 Divw,
29+ Jump,
30+ Li,
2731 Mul,
2832 Or,
2933 Remw,
@@ -39,8 +43,12 @@ const char*[] instr_names = {
3943 [RV64_InstrKind.Add] = "add",
4044 [RV64_InstrKind.AddIw] = "addiw",
4145 [RV64_InstrKind.And] = "and",
42- [RV64_InstrKind.Divw] = "divw",
46+ [RV64_InstrKind.Beqz] = "beqz",
47+ [RV64_InstrKind.Bnez] = "bnez",
48+ [RV64_InstrKind.Divw] = "divw",
49+ [RV64_InstrKind.Jump] = "j",
4350 [RV64_InstrKind.Mul] = "mul",
51+ [RV64_InstrKind.Li] = "li",
4452 [RV64_InstrKind.Or] = "or",
4553 [RV64_InstrKind.Remw] = "remw",
4654 [RV64_InstrKind.Ret] = "ret",
@@ -150,6 +158,21 @@ fn void instructionSelection(Tools* t, ir.FunctionInfo* f) {
150158 break;
151159 // Comparisons
152160 case CmpNe:
161+ // combine Cmp + JmpIf into one beq(z) + jump
162+ assert(j+1 != last);
163+ Instr* next = &instrs[j+1];
164+ assert(next.getKind() == JmpIf);
165+ if (ii.args[1].isZero()) {
166+ // change cmp ne + jmp_if -> beqz (then) + j (else)
167+ ii.setArch(RV64_InstrKind.Bnez);
168+ ii.instrBits.has_result = 0;
169+ ii.args[1].init(Block, b.dests[0]);
170+ } else {
171+ assert(0); // TODO
172+ }
173+ next.setArch(RV64_InstrKind.Jump);
174+ next.args[0].init(Block, b.dests[1]);
175+ next.args[1].clear();
153176 break;
154177 case CmpEq:
155178 break;
@@ -167,6 +190,12 @@ fn void instructionSelection(Tools* t, ir.FunctionInfo* f) {
167190 case Load2:
168191 break;
169192 case Load4:
193+ if (ii.args[0].isConstant()) {
194+ ii.setArch(RV64_InstrKind.Li);
195+ // TODO if zero, use 'zero', skip copy
196+ } else {
197+ // TODO mov?
198+ }
170199 break;
171200 case Load8:
172201 break;
@@ -187,8 +216,11 @@ fn void instructionSelection(Tools* t, ir.FunctionInfo* f) {
187216 break;
188217 // Jump instructions
189218 case Jmp:
219+ ii.setArch(RV64_InstrKind.Jump);
220+ ii.args[0].init(Block, b.dests[0]);
190221 break;
191222 case JmpIf:
223+ assert(0); // should be removed already
192224 break;
193225 case Ret:
194226 ii.setArch(RV64_InstrKind.Ret);
@@ -198,6 +230,7 @@ fn void instructionSelection(Tools* t, ir.FunctionInfo* f) {
198230 case Call:
199231 break;
200232 case Copy:
233+ // NOTE: leave copies in for now, can be removed during register allocation
201234 break;
202235 // Pseudo instructions (must be converted before converting to ASM)
203236 case Arch:
@@ -229,30 +262,38 @@ fn void generateAsm(string_buffer.Buf* out, const char* name, const FunctionInfo
229262 out.add(":\n");
230263 u32 num_blocks = fi.blocks.getCount();
231264 const Block* blocks = fi.blocks.get(0);
232- const Instr* instrs = fi.instructions.get(0);
265+ Instr* instrs = fi.instructions.get(0);
233266
234267 for (u32 blk_id = 0; blk_id < num_blocks; blk_id++) {
235268 const Block* b = &blocks[blk_id];
236- out.print("# %s.%d:\n", b.getKindName(), blk_id);
269+ if (blk_id == 0) out.add("# ");
270+ out.print(".BB%d_%d:\n", fi.id, blk_id);
237271 u32 last = b.instr.start + b.instr.count;
238272 u32 num_arg = 0;
239273 for (u32 j = b.instr.start; j < last; j++) {
240- const Instr* ii = &instrs[j];
274+ Instr* ii = &instrs[j];
241275 bool first = true;
242276 if (ii.isNone()) continue;
243- assert(ii.isArch());
277+ if (!ii.isArch()) {
278+ assert(ii.isCopy());
279+ if (ii.args[0].isValue()) {
280+ ii.setArch(RV64_InstrKind.Li);
281+ } else {
282+ assert(0); // TODO
283+ }
284+ }
244285 out.print("\t%-8s", instr_names[ii.instrBits.arch_instr]);
245286 if (ii.hasResult()) {
246287 assert(ii.hasRegister());
247288 out.print("%s", reg_names[ii.getRegister()]);
248289 first = false;
249290 }
250291 for (u32 i = 0; i < 2; i++) {
251- if (ii.args[0 ].isNone()) break;
292+ if (ii.args[i ].isNone()) break;
252293 if (!first) {
253294 out.add(", ");
254- first = false;
255295 }
296+ first = false;
256297 const Ref* r = &ii.args[i];
257298 switch (r.getKind()) {
258299 case None:
@@ -292,9 +333,7 @@ fn void generateAsm(string_buffer.Buf* out, const char* name, const FunctionInfo
292333 out.print("%s", reg_names[r.value]);
293334 break;
294335 case Block:
295- assert(0); // TODO
296- //Block* b = ph.blocks.get((u32)r.value);
297- //out.print("@%s.%d", b.getKindName(), r.value);
336+ out.print(".BB%d_%d", fi.id, r.value);
298337 break;
299338 case PhiClause:
300339 case CallNumArgs:
0 commit comments