diff options
-rw-r--r-- | src/determine_slotting.c | 254 |
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 |