1
3 package jminusminus;
4
5 import static jminusminus.CLConstants.*;
6 import static jminusminus.NPhysicalRegister.*;
7 import java.util.ArrayList;
8
9
12
13 abstract class NHIRInstruction {
14
15
19 protected static String[] hirMnemonic;
20 static {
21 hirMnemonic = new String[256];
22 hirMnemonic[IADD] = "+";
23 hirMnemonic[ISUB] = "-";
24 hirMnemonic[IMUL] = "*";
25 hirMnemonic[MULTIANEWARRAY] = "multianewarray";
26 hirMnemonic[AALOAD] = "aaload";
27 hirMnemonic[IALOAD] = "iaload";
28 hirMnemonic[IASTORE] = "iastore";
29 hirMnemonic[IF_ICMPNE] = "!=";
30 hirMnemonic[IF_ICMPGT] = ">";
31 hirMnemonic[IF_ICMPLE] = "<=";
32 hirMnemonic[GETSTATIC] = "getstatic";
33 hirMnemonic[PUTSTATIC] = "putstatic";
34 hirMnemonic[INVOKESPECIAL] = "invokespecial";
35 hirMnemonic[INVOKESTATIC] = "invokestatic";
36 hirMnemonic[ARETURN] = "areturn";
37 hirMnemonic[RETURN] = "return";
38 hirMnemonic[IRETURN] = "ireturn";
39 }
40
41
42 public NBasicBlock block;
43
44
45 public int id;
46
47
48 public String sType;
49
50
51 public String lType;
52
53
54 public NLIRInstruction lir;
55
56
64
65 protected NHIRInstruction(NBasicBlock block, int id) {
66 this(block, id, "", "");
67 }
68
69
81
82 protected NHIRInstruction(NBasicBlock block, int id, String sType,
83 String lType) {
84 this.block = block;
85 this.id = id;
86 this.sType = sType;
87 this.lType = lType;
88 }
89
90
98
99 public boolean equals(NHIRInstruction other) {
100 return this.id == other.id;
101 }
102
103
111
112 public NLIRInstruction toLir() {
113 return null;
114 }
115
116
123
124 public String id() {
125 return sType + id;
126 }
127
128
133
134 public String toString() {
135 return sType + id;
136 }
137
138 }
139
140
143
144 class NHIRArithmetic extends NHIRInstruction {
145
146
147 public int opcode;
148
149
150 public int lhs;
151
152
153 public int rhs;
154
155
169
170 public NHIRArithmetic(NBasicBlock block, int id, int opcode, int lhs,
171 int rhs) {
172 super(block, id, "I", "I");
173 this.opcode = opcode;
174 this.lhs = lhs;
175 this.rhs = rhs;
176 }
177
178
181
182 public NLIRInstruction toLir() {
183 if (lir != null) {
184 return lir;
185 }
186 NLIRInstruction ins1 = block.cfg.hirMap.get(lhs).toLir();
187 NLIRInstruction ins2 = block.cfg.hirMap.get(rhs).toLir();
188 lir = new NLIRArithmetic(block, NControlFlowGraph.lirId++, opcode,
189 ins1, ins2);
190 block.lir.add(lir);
191 return lir;
192 }
193
194
197
198 public String toString() {
199 return id() + ": " + block.cfg.hirMap.get(lhs).id() + " "
200 + hirMnemonic[opcode] + " " + block.cfg.hirMap.get(rhs).id();
201 }
202
203 }
204
205
209
210 class NHIRIntConstant extends NHIRInstruction {
211
212
213 public int value;
214
215
225
226 public NHIRIntConstant(NBasicBlock block, int id, int value) {
227 super(block, id, "I", "I");
228 this.value = value;
229 }
230
231
234
235 public NLIRInstruction toLir() {
236 if (lir != null) {
237 return lir;
238 }
239 lir = new NLIRIntConstant(block, NControlFlowGraph.lirId++, value);
240 block.lir.add(lir);
241 return lir;
242 }
243
244
247
248 public String toString() {
249 return id() + ": " + value;
250 }
251
252 }
253
254
258
259 class NHIRStringConstant extends NHIRInstruction {
260
261
262 public String value;
263
264
274
275 public NHIRStringConstant(NBasicBlock block, int id, String value) {
276 super(block, id, "L", "Ljava/lang/String;");
277 this.value = value;
278 }
279
280
283
284 public NLIRInstruction toLir() {
285 if (lir != null) {
286 return lir;
287 }
288 lir = new NLIRStringConstant(block, NControlFlowGraph.lirId++, value);
289 block.lir.add(lir);
290 return lir;
291 }
292
293
296
297 public String toString() {
298 return id() + ": " + value;
299 }
300
301 }
302
303
306
307 class NHIRConditionalJump extends NHIRInstruction {
308
309
310 public int lhs;
311
312
313 public int rhs;
314
315
316 public int opcode;
317
318
319 public NBasicBlock onTrueDestination;
320
321
322 public NBasicBlock onFalseDestination;
323
324
342
343 public NHIRConditionalJump(NBasicBlock block, int id, int lhs, int rhs,
344 int opcode, NBasicBlock onTrueDestination,
345 NBasicBlock onFalseDestination) {
346 super(block, id, "", "");
347 this.lhs = lhs;
348 this.rhs = rhs;
349 this.opcode = opcode;
350 this.onTrueDestination = onTrueDestination;
351 this.onFalseDestination = onFalseDestination;
352 }
353
354
357
358 public NLIRInstruction toLir() {
359 if (lir != null) {
360 return lir;
361 }
362 NLIRInstruction ins1 = block.cfg.hirMap.get(lhs).toLir();
363 NLIRInstruction ins2 = block.cfg.hirMap.get(rhs).toLir();
364 lir = new NLIRConditionalJump(block, NControlFlowGraph.lirId++, ins1,
365 ins2, opcode, onTrueDestination, onFalseDestination);
366 block.lir.add(lir);
367 return lir;
368 }
369
370
373
374 public String toString() {
375 return id() + ": if " + block.cfg.hirMap.get(lhs).id() + " "
376 + hirMnemonic[opcode] + " " + block.cfg.hirMap.get(rhs).id()
377 + " then " + onTrueDestination.id() + " else "
378 + onFalseDestination.id();
379 }
380
381 }
382
383
386
387 class NHIRGoto extends NHIRInstruction {
388
389
390 public NBasicBlock destination;
391
392
402
403 public NHIRGoto(NBasicBlock block, int id, NBasicBlock destination) {
404 super(block, id, "", "");
405 this.destination = destination;
406 }
407
408
411
412 public NLIRInstruction toLir() {
413 if (lir != null) {
414 return lir;
415 }
416 lir = new NLIRGoto(block, NControlFlowGraph.lirId++, destination);
417 block.lir.add(lir);
418 return lir;
419 }
420
421
424
425 public String toString() {
426 return id() + ": goto " + destination.id();
427 }
428
429 }
430
431
434
435 class NHIRInvoke extends NHIRInstruction {
436
437
438 public int opcode;
439
440
441 public String target;
442
443
444 public String name;
445
446
447 public ArrayList<Integer> arguments;
448
449
469
470 public NHIRInvoke(NBasicBlock block, int id, int opcode, String target,
471 String name, ArrayList<Integer> arguments, String sType,
472 String lType) {
473 super(block, id, sType, lType);
474 this.opcode = opcode;
475 this.target = target;
476 this.name = name;
477 this.arguments = arguments;
478 }
479
480
483
484 public NLIRInstruction toLir() {
485 if (lir != null) {
486 return lir;
487 }
488
489 if (this.arguments.size() - 4 > block.cfg.offset) {
494 block.cfg.offset = this.arguments.size() - 4;
495 }
496
497 ArrayList<NRegister> arguments = new ArrayList<NRegister>();
498 ArrayList<NPhysicalRegister> froms = new ArrayList<NPhysicalRegister>();
499 ArrayList<NVirtualRegister> tos = new ArrayList<NVirtualRegister>();
500 for (int i = 0; i < this.arguments.size(); i++) {
501 int arg = this.arguments.get(i);
502 NLIRInstruction ins = block.cfg.hirMap.get(arg).toLir();
503 if (i < 4) {
504 String sType = block.cfg.hirMap.get(arg).sType;
510 String lType = block.cfg.hirMap.get(arg).lType;
511 NPhysicalRegister from = NPhysicalRegister.regInfo[A0 + i];
512 block.cfg.registers.set(A0 + i, from);
513 NVirtualRegister to = new NVirtualRegister(
514 NControlFlowGraph.regId++, sType, lType);
515 block.cfg.registers.add(to);
516 NLIRMove move1 = new NLIRMove(block, NControlFlowGraph.lirId++,
517 from, to);
518 block.lir.add(move1);
519 NLIRMove move2 = new NLIRMove(block, NControlFlowGraph.lirId++,
520 ins.write, from);
521 block.lir.add(move2);
522 arguments.add(NPhysicalRegister.regInfo[A0 + i]);
523
524 froms.add(from);
528 tos.add(to);
529 } else {
530 NLIRStore store = new NLIRStore(block,
531 NControlFlowGraph.lirId++, i - 4, OffsetFrom.SP,
532 ins.write);
533 block.lir.add(store);
534 arguments.add(ins.write);
535 }
536 }
537
538 lir = new NLIRInvoke(block, NControlFlowGraph.lirId++, opcode, target,
539 name, arguments, sType, lType);
540 block.lir.add(lir);
541
542 if (lir.write != null) {
546 NVirtualRegister to = new NVirtualRegister(
547 NControlFlowGraph.regId++, sType, lType);
548 NLIRMove move = new NLIRMove(block, NControlFlowGraph.lirId++,
549 NPhysicalRegister.regInfo[V0], to);
550 block.cfg.registers.add(to);
551 block.lir.add(move);
552 lir = move;
553 }
554
555 for (int i = 0; i < tos.size(); i++) {
558 NLIRMove move = new NLIRMove(block, NControlFlowGraph.lirId++, tos
559 .get(i), froms.get(i));
560 block.lir.add(move);
561 }
562
563 return lir;
564 }
565
566
569
570 public String toString() {
571 String s = id() + ": " + hirMnemonic[opcode] + " " + target + "."
572 + name + "( ";
573 for (int arg : arguments) {
574 s += block.cfg.hirMap.get(arg).id() + " ";
575 }
576 s += ")";
577 return s;
578 }
579
580 }
581
582
585
586 class NHIRReturn extends NHIRInstruction {
587
588
589 public int opcode;
590
591
592 public int value;
593
594
606
607 public NHIRReturn(NBasicBlock block, int id, int opcode, int value) {
608 super(block, id,
609 (value == -1) ? "" : block.cfg.hirMap.get(value).sType,
610 (value == -1) ? "" : block.cfg.hirMap.get(value).lType);
611 this.opcode = opcode;
612 this.value = value;
613 }
614
615
618
619 public NLIRInstruction toLir() {
620 if (lir != null) {
621 return lir;
622 }
623 NLIRInstruction result = null;
624 if (value != -1) {
625 result = block.cfg.hirMap.get(value).toLir();
626 NLIRMove move = new NLIRMove(block, NControlFlowGraph.lirId++,
627 result.write, NPhysicalRegister.regInfo[V0]);
628 block.lir.add(move);
629 block.cfg.registers.set(V0, NPhysicalRegister.regInfo[V0]);
630 }
631 lir = new NLIRReturn(block, NControlFlowGraph.lirId++, opcode,
632 (result == null) ? null : NPhysicalRegister.regInfo[V0]);
633 block.lir.add(lir);
634 return lir;
635 }
636
637
640
641 public String toString() {
642 if (value == -1) {
643 return id() + ": " + hirMnemonic[opcode];
644 }
645 return id() + ": " + hirMnemonic[opcode] + " "
646 + block.cfg.hirMap.get(value).id();
647 }
648
649 }
650
651
654
655 class NHIRPutField extends NHIRInstruction {
656
657
658 public int opcode;
659
660
661 public String target;
662
663
664 public String name;
665
666
667 public int value;
668
669
689
690 public NHIRPutField(NBasicBlock block, int id, int opcode, String target,
691 String name, String sType, String lType, int value) {
692 super(block, id, sType, lType);
693 this.opcode = opcode;
694 this.target = target;
695 this.name = name;
696 this.value = value;
697 }
698
699
702
703 public NLIRInstruction toLir() {
704 if (lir != null) {
705 return lir;
706 }
707 NLIRInstruction result = block.cfg.hirMap.get(value).toLir();
708 lir = new NLIRPutField(block, NControlFlowGraph.lirId++, opcode,
709 target, name, sType, lType, result);
710 block.lir.add(lir);
711 return lir;
712 }
713
714
717
718 public String toString() {
719 return id() + ": " + hirMnemonic[opcode] + " " + target + "." + name
720 + " = " + block.cfg.hirMap.get(value).id();
721 }
722
723 }
724
725
728
729 class NHIRGetField extends NHIRInstruction {
730
731
732 public int opcode;
733
734
735 public String target;
736
737
738 public String name;
739
740
758
759 public NHIRGetField(NBasicBlock block, int id, int opcode, String target,
760 String name, String sType, String lType) {
761 super(block, id, sType, lType);
762 this.opcode = opcode;
763 this.target = target;
764 this.name = name;
765 }
766
767
770
771 public NLIRInstruction toLir() {
772 if (lir != null) {
773 return lir;
774 }
775 lir = new NLIRGetField(block, NControlFlowGraph.lirId++, opcode,
776 target, name, sType, lType);
777 block.lir.add(lir);
778 return lir;
779 }
780
781
784
785 public String toString() {
786 return id() + ": " + hirMnemonic[opcode] + " " + target + "." + name;
787 }
788
789 }
790
791
794
795 class NHIRNewArray extends NHIRInstruction {
796
797
798 public int opcode;
799
800
801 public int dim;
802
803
819
820 public NHIRNewArray(NBasicBlock block, int id, int opcode, int dim,
821 String sType, String lType) {
822 super(block, id, lType, sType);
823 this.opcode = opcode;
824 this.dim = dim;
825 }
826
827
830
831 public NLIRInstruction toLir() {
832 if (lir != null) {
833 return lir;
834 }
835 lir = new NLIRNewArray(block, NControlFlowGraph.lirId++, opcode, dim,
836 sType, lType);
837 block.lir.add(lir);
838 return lir;
839 }
840
841
844
845 public String toString() {
846 return id() + ": " + hirMnemonic[opcode] + " " + lType + " [" + dim
847 + "]";
848 }
849
850 }
851
852
855
856 class NHIRALoad extends NHIRInstruction {
857
858
859 public int opcode;
860
861
862 public int arrayRef;
863
864
865 public int index;
866
867
885
886 public NHIRALoad(NBasicBlock block, int id, int opcode, int arrayRef,
887 int index, String sType, String lType) {
888 super(block, id, sType, lType);
889 this.opcode = opcode;
890 this.arrayRef = arrayRef;
891 this.index = index;
892 }
893
894
897
898 public NLIRInstruction toLir() {
899 if (lir != null) {
900 return lir;
901 }
902 NLIRInstruction arrayRef = block.cfg.hirMap.get(this.arrayRef).toLir();
903 NLIRInstruction index = block.cfg.hirMap.get(this.index).toLir();
904 lir = new NLIRALoad(block, NControlFlowGraph.lirId++, opcode, arrayRef,
905 index, sType, lType);
906 block.lir.add(lir);
907 return lir;
908 }
909
910
913
914 public String toString() {
915 return id() + ": " + hirMnemonic[opcode] + " "
916 + block.cfg.hirMap.get(arrayRef).id() + "["
917 + block.cfg.hirMap.get(index).id() + "]";
918 }
919
920 }
921
922
925
926 class NHIRAStore extends NHIRInstruction {
927
928
929 public int opcode;
930
931
932 public int arrayRef;
933
934
935 public int index;
936
937
938 public int value;
939
940
960
961 public NHIRAStore(NBasicBlock block, int id, int opcode, int arrayRef,
962 int index, int value, String sType, String lType) {
963 super(block, id, sType, lType);
964 this.opcode = opcode;
965 this.arrayRef = arrayRef;
966 this.index = index;
967 this.value = value;
968 }
969
970
973
974 public NLIRInstruction toLir() {
975 if (lir != null) {
976 return lir;
977 }
978 NLIRInstruction arrayRef = block.cfg.hirMap.get(this.arrayRef).toLir();
979 NLIRInstruction index = block.cfg.hirMap.get(this.index).toLir();
980 NLIRInstruction value = block.cfg.hirMap.get(this.value).toLir();
981 lir = new NLIRAStore(block, NControlFlowGraph.lirId++, opcode,
982 arrayRef, index, value, sType, lType);
983 block.lir.add(lir);
984 return lir;
985 }
986
987
990
991 public String toString() {
992 return id() + ": " + hirMnemonic[opcode] + " "
993 + block.cfg.hirMap.get(arrayRef).id() + "["
994 + block.cfg.hirMap.get(index).id() + "] = "
995 + block.cfg.hirMap.get(value).id();
996 }
997
998 }
999
1000
1003
1004class NHIRPhiFunction extends NHIRInstruction {
1005
1006
1007 public ArrayList<Integer> arguments;
1008
1009
1010 public int local;
1011
1012
1024
1025 public NHIRPhiFunction(NBasicBlock block, int id,
1026 ArrayList<Integer> arguments, int local) {
1027 super(block, id, "", "");
1028 this.arguments = arguments;
1029 this.local = local;
1030 }
1031
1032
1036
1037 public void inferType() {
1038 for (int arg : arguments) {
1039 if (!block.cfg.hirMap.get(arguments.get(0)).sType.equals("")) {
1040 sType = block.cfg.hirMap.get(arguments.get(0)).sType;
1041 lType = block.cfg.hirMap.get(arguments.get(0)).lType;
1042 break;
1043 }
1044 }
1045 }
1046
1047
1050
1051 public NLIRInstruction toLir() {
1052 if (lir != null) {
1053 return lir;
1054 }
1055 lir = new NLIRPhiFunction(block, NControlFlowGraph.lirId++, sType,
1056 lType);
1057 return lir;
1058 }
1059
1060
1063
1064 public String toString() {
1065 String s = "[ ";
1066 for (int ins : arguments) {
1067 if (block.cfg.hirMap.get(ins) != null)
1068 s += block.cfg.hirMap.get(ins).sType + ins + " ";
1069 }
1070 s += "]";
1071 return s;
1072 }
1073
1074}
1075
1076
1079
1080class NHIRLoadLocal extends NHIRInstruction {
1081
1082
1083 public int local;
1084
1085
1099
1100 public NHIRLoadLocal(NBasicBlock block, int id, int local, String sType,
1101 String lType) {
1102 super(block, id, sType, lType);
1103 this.local = local;
1104 }
1105
1106
1109
1110 public NLIRInstruction toLir() {
1111 if (lir != null) {
1112 return lir;
1113 }
1114 lir = new NLIRLoadLocal(block, NControlFlowGraph.lirId++, local, sType,
1115 lType);
1116 block.lir.add(lir);
1117 return lir;
1118 }
1119
1120
1123
1124 public String toString() {
1125 return id() + ": LDLOC " + local;
1126 }
1127
1128}
1129
1130
1133
1134class NHIRLocal extends NHIRInstruction {
1135
1136
1137 public int local;
1138
1139
1153
1154 public NHIRLocal(NBasicBlock block, int id, int local, String sType,
1155 String lType) {
1156 super(block, id, sType, lType);
1157 this.local = local;
1158 }
1159
1160
1163
1164 public String toString() {
1165 return id() + ": LOC " + lType;
1166 }
1167
1168}
1169