summaryrefslogtreecommitdiff
path: root/src/determine_slotting.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/determine_slotting.c')
-rw-r--r--src/determine_slotting.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/determine_slotting.c b/src/determine_slotting.c
new file mode 100644
index 0000000..f366433
--- /dev/null
+++ b/src/determine_slotting.c
@@ -0,0 +1,254 @@
+#define SLOT_E 'E'
+#define SLOT_U 'U'
+#define SLOT_L 'L'
+
+#if defined DEBUG && DEBUG == 1
+
+#include <stdio.h>
+
+#define PRINT_DEBUG printf("%c%c%c%c\n", slot._3, slot._2, slot._1, slot._0)
+
+#define RULE1() \
+ slot._3 = 'U'; \
+ slot._2 = 'U'; \
+ slot._1 = 'U'; \
+ slot._0 = 'U'
+
+#define RULE2() \
+ slot._3 = 'E'; \
+ slot._2 = 'U'; \
+ slot._1 = 'U'; \
+ slot._0 = 'U'
+
+#define RULE3() \
+ slot._3 = 'U'; \
+ slot._2 = 'U'; \
+ slot._1 = 'E'; \
+ slot._0 = 'L'
+
+#define RULE3B() \
+ slot._3 = 'E'; \
+ slot._2 = 'E'; \
+ slot._1 = 'L'; \
+ slot._0 = 'L'
+
+#define RULE4C() \
+ slot._3 = 'E'; \
+ slot._2 = 'E'; \
+ slot._1 = 'E'; \
+ slot._0 = 'U'
+
+#define RULE4A() \
+ slot._3 = 'E'; \
+ slot._2 = 'L'; \
+ slot._1 = 'E'; \
+ slot._0 = 'U'
+
+#define RULE4AD() \
+ slot._3 = 'U'; \
+ slot._2 = 'L'; \
+ slot._1 = 'E'; \
+ slot._0 = 'E'
+
+#define RULE4CD() \
+ slot._3 = 'E'; \
+ slot._2 = 'E'; \
+ slot._1 = 'E'; \
+ slot._0 = 'E'
+
+#endif /* DEBUG */
+
+struct slotting_t
+{
+ int _3;
+ int _2;
+ int _1;
+ int _0;
+};
+
+static inline int
+number_slotted(struct slotting_t slot, int which)
+{
+ int num = 0;
+
+ if (slot._3 == which) ++num;
+ if (slot._2 == which) ++num;
+ if (slot._1 == which) ++num;
+ if (slot._0 == which) ++num;
+
+ return num;
+}
+
+static inline struct slotting_t
+replace_E_with(struct slotting_t slot, int which)
+{
+ if (slot._3 == SLOT_E) slot._3 = which;
+ if (slot._2 == SLOT_E) slot._2 = which;
+ if (slot._1 == SLOT_E) slot._1 = which;
+ if (slot._0 == SLOT_E) slot._0 = which;
+
+ return slot;
+}
+
+struct slotting_t
+determine_slotting(struct slotting_t slot)
+{
+ int slotted_E = number_slotted(slot, SLOT_E);
+
+ /* Ebox slotting rules; Compiler Writer's Guide for the Alpha 21264, pg 69
+ * A.1 Rule 1 - Four of a Kind
+ * if all instructions are slotted U or all instructios are slotted L,
+ * then the classification is honored.
+ */
+ if (slotted_E == 0)
+ {
+ return slot;
+ }
+
+ /* Ebox slotting rules; Compiler Writer's Guide for the Alpha 21264, pg 69-70
+ * A.2 Rule 2a - Three of a Kind
+ * if and only if three instructions are slotted U,
+ * then the classification is honored and the other instruction is slotted L.
+ * A.3 Rule 3a - Two of a Kind
+ * if and only if two instructions are slotted U,
+ * then the classification is honored and the other instructions are slotted L.
+ */
+ if ((number_slotted(slot, SLOT_U) == 3)
+ || (number_slotted(slot, SLOT_U) == 2))
+ {
+ return replace_E_with(slot, SLOT_L);
+ }
+
+ /* Ebox slotting rules; Compiler Writer's Guide for the Alpha 21264, pg 70
+ * A.2 Rule 2b - Three of a Kind
+ * if and only if three instructions are slotted L,
+ * then the classification is honored and the other instruction is slotted U.
+ * A.3 Rule 3b - Two of a Kind
+ * if and only if two instructions are slotted L,
+ * then the classification is honored and the other instructions are slotted U.
+ */
+ if ((number_slotted(slot, SLOT_L) == 3)
+ || (number_slotted(slot, SLOT_L) == 2))
+ {
+ return replace_E_with(slot, SLOT_U);
+ }
+
+ /* Ebox slotting rules; Compiler Writer's Guide for the Alpha 21264, pg 70
+ * A.4 Rule 4c - One of a Kind and None of a Kind
+ * if both instructions in the second quadword are slotted E,
+ * then the first is slotted L and the second slotted U.
+ */
+ if ((slot._3 == SLOT_E) && (slot._2 == SLOT_E))
+ {
+ slot._3 = SLOT_U;
+ slot._2 = SLOT_L;
+
+ slotted_E -= 2;
+ }
+
+ if (slotted_E == 0)
+ {
+ return slot;
+ }
+
+ /* check low quad for single U */
+ if ((slot._1 == SLOT_U) != (slot._0 == SLOT_U))
+ {
+ if (slot._0 == SLOT_E)
+ {
+ slot._0 = SLOT_L;
+ }
+ else
+ {
+ slot._1 = SLOT_L;
+ }
+
+ --slotted_E;
+ }
+ /* check low quad for single L */
+ else if ((slot._1 == SLOT_L) != (slot._0 == SLOT_L))
+ {
+ if (slot._0 == SLOT_E)
+ {
+ slot._0 = SLOT_U;
+ }
+ else
+ {
+ slot._1 = SLOT_U;
+ }
+
+ --slotted_E;
+ }
+
+ if (slotted_E == 0)
+ {
+ return slot;
+ }
+
+#if defined DEBUG && DEBUG == 1
+ PRINT_DEBUG;
+#endif
+
+ /* check high quad for single U */
+ if ((slot._3 == SLOT_U) != (slot._2 == SLOT_U))
+ {
+ if (slot._2 == SLOT_E)
+ {
+ slot._2 = SLOT_L;
+ }
+ else if (slot._3 == SLOT_E)
+ {
+ slot._3 = SLOT_L;
+ }
+
+ --slotted_E;
+ }
+ /* check high quad for single L */
+ else if ((slot._3 == SLOT_L) != (slot._2 == SLOT_L))
+ {
+ if (slot._2 == SLOT_E)
+ {
+ slot._2 = SLOT_U;
+ }
+ else if (slot._3 == SLOT_E)
+ {
+ slot._3 = SLOT_U;
+ }
+
+ --slotted_E;
+ }
+
+#if defined DEBUG && DEBUG == 1
+ PRINT_DEBUG;
+#endif
+
+ /* if we reach here the only possibility is two Es in the low quad */
+ if (slotted_E != 0)
+ {
+ slot._1 = slot._3;
+ slot._0 = slot._2;
+ }
+
+ return slot;
+}
+
+#if defined DEBUG && DEBUG == 1
+int main() {
+ struct slotting_t slot;
+
+// RULE3();
+// RULE3B();
+// RULE4C();
+ RULE4A();
+// RULE4AD();
+// RULE4CD();
+
+ PRINT_DEBUG;
+
+ slot = determine_slotting(slot);
+
+ PRINT_DEBUG;
+
+ return 0;
+}
+#endif