#include #define SLOT_E 'E' #define SLOT_U 'U' #define SLOT_L 'L' #define CLUSTER_0 0 #define CLUSTER_1 1 #if defined DEBUG && DEBUG == 1 #include #define PRINT_DEBUG printf("%c%c%c%c\n", octaword.instr[3].slot, octaword.instr[2].slot, octaword.instr[1].slot, octaword.instr[0].slot) #define RULE1() \ octaword.instr[3].slot = 'U'; \ octaword.instr[2].slot = 'U'; \ octaword.instr[1].slot = 'U'; \ octaword.instr[0].slot = 'U' #define RULE2() \ octaword.instr[3].slot = 'E'; \ octaword.instr[2].slot = 'U'; \ octaword.instr[1].slot = 'U'; \ octaword.instr[0].slot = 'U' #define RULE3() \ octaword.instr[3].slot = 'U'; \ octaword.instr[2].slot = 'U'; \ octaword.instr[1].slot = 'E'; \ octaword.instr[0].slot = 'L' #define RULE3B() \ octaword.instr[3].slot = 'E'; \ octaword.instr[2].slot = 'E'; \ octaword.instr[1].slot = 'L'; \ octaword.instr[0].slot = 'L' #define RULE4C() \ octaword.instr[3].slot = 'E'; \ octaword.instr[2].slot = 'E'; \ octaword.instr[1].slot = 'E'; \ octaword.instr[0].slot = 'U' #define RULE4A() \ octaword.instr[3].slot = 'E'; \ octaword.instr[2].slot = 'L'; \ octaword.instr[1].slot = 'E'; \ octaword.instr[0].slot = 'U' #define RULE4AD() \ octaword.instr[3].slot = 'U'; \ octaword.instr[2].slot = 'L'; \ octaword.instr[1].slot = 'E'; \ octaword.instr[0].slot = 'E' #define RULE4CD() \ octaword.instr[3].slot = 'E'; \ octaword.instr[2].slot = 'E'; \ octaword.instr[1].slot = 'E'; \ octaword.instr[0].slot = 'E' #endif /* DEBUG */ struct octaword_t { struct { uint8_t slot; uint8_t cluster; } instr[4]; }; static inline int number_slotted(struct octaword_t octaword, uint8_t which) { int num = 0; int i; for (i = 0; i < 4; i++) { if (octaword.instr[i].slot == which) ++num; } return num; } static inline struct octaword_t replace_E_with(struct octaword_t octaword, uint8_t which) { if (octaword.instr[3].slot == SLOT_E) octaword.instr[3].slot = which; if (octaword.instr[2].slot == SLOT_E) octaword.instr[2].slot = which; if (octaword.instr[1].slot == SLOT_E) octaword.instr[1].slot = which; if (octaword.instr[0].slot == SLOT_E) octaword.instr[0].slot = which; return octaword; } struct octaword_t determine_slotting(struct octaword_t octaword) { int slotted_E = number_slotted(octaword, 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 octaword; } /* 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(octaword, SLOT_U) == 3) || (number_slotted(octaword, SLOT_U) == 2)) { return replace_E_with(octaword, 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(octaword, SLOT_L) == 3) || (number_slotted(octaword, SLOT_L) == 2)) { return replace_E_with(octaword, 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 ((octaword.instr[3].slot == SLOT_E) && (octaword.instr[2].slot == SLOT_E)) { octaword.instr[3].slot = SLOT_U; octaword.instr[2].slot = SLOT_L; slotted_E -= 2; } if (slotted_E == 0) { return octaword; } /* check low quad for single U */ if ((octaword.instr[1].slot == SLOT_U) != (octaword.instr[0].slot == SLOT_U)) { if (octaword.instr[0].slot == SLOT_E) { octaword.instr[0].slot = SLOT_L; } else { octaword.instr[1].slot = SLOT_L; } --slotted_E; } /* check low quad for single L */ else if ((octaword.instr[1].slot == SLOT_L) != (octaword.instr[0].slot == SLOT_L)) { if (octaword.instr[0].slot == SLOT_E) { octaword.instr[0].slot = SLOT_U; } else { octaword.instr[1].slot = SLOT_U; } --slotted_E; } if (slotted_E == 0) { return octaword; } #if defined DEBUG && DEBUG == 1 PRINT_DEBUG; #endif /* check high quad for single U */ if ((octaword.instr[3].slot == SLOT_U) != (octaword.instr[2].slot == SLOT_U)) { if (octaword.instr[2].slot == SLOT_E) { octaword.instr[2].slot = SLOT_L; } else if (octaword.instr[3].slot == SLOT_E) { octaword.instr[3].slot = SLOT_L; } --slotted_E; } /* check high quad for single L */ else if ((octaword.instr[3].slot == SLOT_L) != (octaword.instr[2].slot == SLOT_L)) { if (octaword.instr[2].slot == SLOT_E) { octaword.instr[2].slot = SLOT_U; } else if (octaword.instr[3].slot == SLOT_E) { octaword.instr[3].slot = 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) { octaword.instr[1].slot = octaword.instr[3].slot; octaword.instr[0].slot = octaword.instr[2].slot; } return octaword; } #if defined DEBUG && DEBUG == 1 int main() { struct octaword_t octaword; // RULE3(); // RULE3B(); // RULE4C(); RULE4A(); // RULE4AD(); // RULE4CD(); PRINT_DEBUG; octaword = determine_slotting(octaword); PRINT_DEBUG; return 0; } #endif