rename_impl.hh (9918:2c7219e2d999) rename_impl.hh (9919:803903a8dac1)
1/*
2 * Copyright (c) 2010-2012 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating

--- 857 unchanged lines hidden (view full) ---

866 // but the ROB may still be squashing instructions.
867 if (historyBuffer[tid].empty()) {
868 return;
869 }
870
871 // Go through the most recent instructions, undoing the mappings
872 // they did and freeing up the registers.
873 while (!historyBuffer[tid].empty() &&
1/*
2 * Copyright (c) 2010-2012 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating

--- 857 unchanged lines hidden (view full) ---

866 // but the ROB may still be squashing instructions.
867 if (historyBuffer[tid].empty()) {
868 return;
869 }
870
871 // Go through the most recent instructions, undoing the mappings
872 // they did and freeing up the registers.
873 while (!historyBuffer[tid].empty() &&
874 (*hb_it).instSeqNum > squashed_seq_num) {
874 hb_it->instSeqNum > squashed_seq_num) {
875 assert(hb_it != historyBuffer[tid].end());
876
877 DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
875 assert(hb_it != historyBuffer[tid].end());
876
877 DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
878 "number %i.\n", tid, (*hb_it).instSeqNum);
878 "number %i.\n", tid, hb_it->instSeqNum);
879
879
880 // Tell the rename map to set the architected register to the
881 // previous physical register that it was renamed to.
882 renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
880 // Undo the rename mapping only if it was really a change.
881 // Special regs that are not really renamed (like misc regs
882 // and the zero reg) can be recognized because the new mapping
883 // is the same as the old one. While it would be merely a
884 // waste of time to update the rename table, we definitely
885 // don't want to put these on the free list.
886 if (hb_it->newPhysReg != hb_it->prevPhysReg) {
887 // Tell the rename map to set the architected register to the
888 // previous physical register that it was renamed to.
889 renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
883
890
884 // Put the renamed physical register back on the free list.
885 freeList->addReg(hb_it->newPhysReg);
891 // Put the renamed physical register back on the free list.
892 freeList->addReg(hb_it->newPhysReg);
893 }
886
887 historyBuffer[tid].erase(hb_it++);
888
889 ++renameUndoneMaps;
890 }
891}
892
893template<class Impl>

--- 19 unchanged lines hidden (view full) ---

913 }
914
915 // Commit all the renames up until (and including) the committed sequence
916 // number. Some or even all of the committed instructions may not have
917 // rename histories if they did not have destination registers that were
918 // renamed.
919 while (!historyBuffer[tid].empty() &&
920 hb_it != historyBuffer[tid].end() &&
894
895 historyBuffer[tid].erase(hb_it++);
896
897 ++renameUndoneMaps;
898 }
899}
900
901template<class Impl>

--- 19 unchanged lines hidden (view full) ---

921 }
922
923 // Commit all the renames up until (and including) the committed sequence
924 // number. Some or even all of the committed instructions may not have
925 // rename histories if they did not have destination registers that were
926 // renamed.
927 while (!historyBuffer[tid].empty() &&
928 hb_it != historyBuffer[tid].end() &&
921 (*hb_it).instSeqNum <= inst_seq_num) {
929 hb_it->instSeqNum <= inst_seq_num) {
922
923 DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, "
924 "[sn:%lli].\n",
930
931 DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, "
932 "[sn:%lli].\n",
925 tid, (*hb_it).prevPhysReg, (*hb_it).instSeqNum);
933 tid, hb_it->prevPhysReg, hb_it->instSeqNum);
926
934
927 freeList->addReg((*hb_it).prevPhysReg);
935 // Don't free special phys regs like misc and zero regs, which
936 // can be recognized because the new mapping is the same as
937 // the old one.
938 if (hb_it->newPhysReg != hb_it->prevPhysReg) {
939 freeList->addReg(hb_it->prevPhysReg);
940 }
941
928 ++renameCommittedMaps;
929
930 historyBuffer[tid].erase(hb_it--);
931 }
932}
933
934template <class Impl>
935inline void
936DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
937{
942 ++renameCommittedMaps;
943
944 historyBuffer[tid].erase(hb_it--);
945 }
946}
947
948template <class Impl>
949inline void
950DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
951{
938 assert(renameMap[tid] != 0);
939
952 ThreadContext *tc = inst->tcBase();
953 RenameMap *map = renameMap[tid];
940 unsigned num_src_regs = inst->numSrcRegs();
941
942 // Get the architectual register numbers from the source and
954 unsigned num_src_regs = inst->numSrcRegs();
955
956 // Get the architectual register numbers from the source and
943 // destination operands, and redirect them to the right register.
944 // Will need to mark dependencies though.
957 // operands, and redirect them to the right physical register.
945 for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
946 RegIndex src_reg = inst->srcRegIdx(src_idx);
958 for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
959 RegIndex src_reg = inst->srcRegIdx(src_idx);
947 RegIndex flat_src_reg = src_reg;
948 switch (regIdxToClass(src_reg)) {
960 RegIndex rel_src_reg;
961 RegIndex flat_rel_src_reg;
962 PhysRegIndex renamed_reg;
963
964 switch (regIdxToClass(src_reg, &rel_src_reg)) {
949 case IntRegClass:
965 case IntRegClass:
950 flat_src_reg = inst->tcBase()->flattenIntIndex(src_reg);
951 DPRINTF(Rename, "Flattening index %d to %d.\n",
952 (int)src_reg, (int)flat_src_reg);
966 flat_rel_src_reg = tc->flattenIntIndex(rel_src_reg);
967 renamed_reg = map->lookupInt(flat_rel_src_reg);
968 intRenameLookups++;
953 break;
954
955 case FloatRegClass:
969 break;
970
971 case FloatRegClass:
956 src_reg = src_reg - TheISA::FP_Reg_Base;
957 flat_src_reg = inst->tcBase()->flattenFloatIndex(src_reg);
958 DPRINTF(Rename, "Flattening index %d to %d.\n",
959 (int)src_reg, (int)flat_src_reg);
960 flat_src_reg += TheISA::NumIntRegs;
972 flat_rel_src_reg = tc->flattenFloatIndex(rel_src_reg);
973 renamed_reg = map->lookupFloat(flat_rel_src_reg);
974 fpRenameLookups++;
961 break;
962
963 case MiscRegClass:
975 break;
976
977 case MiscRegClass:
964 flat_src_reg = src_reg - TheISA::Misc_Reg_Base +
965 TheISA::NumFloatRegs + TheISA::NumIntRegs;
966 DPRINTF(Rename, "Adjusting reg index from %d to %d.\n",
967 src_reg, flat_src_reg);
978 // misc regs don't get flattened
979 flat_rel_src_reg = rel_src_reg;
980 renamed_reg = map->lookupMisc(flat_rel_src_reg);
968 break;
969
970 default:
971 panic("Reg index is out of bound: %d.", src_reg);
972 }
973
981 break;
982
983 default:
984 panic("Reg index is out of bound: %d.", src_reg);
985 }
986
974 // Look up the source registers to get the phys. register they've
975 // been renamed to, and set the sources to those registers.
976 PhysRegIndex renamed_reg = renameMap[tid]->lookup(flat_src_reg);
987 DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i (flattened %i), "
988 "got phys reg %i\n", tid, RegClassStrings[regIdxToClass(src_reg)],
989 (int)src_reg, (int)flat_rel_src_reg, (int)renamed_reg);
977
990
978 DPRINTF(Rename, "[tid:%u]: Looking up arch reg %i, got "
979 "physical reg %i.\n", tid, (int)flat_src_reg,
980 (int)renamed_reg);
981
982 inst->renameSrcReg(src_idx, renamed_reg);
983
984 // See if the register is ready or not.
991 inst->renameSrcReg(src_idx, renamed_reg);
992
993 // See if the register is ready or not.
985 if (scoreboard->getReg(renamed_reg) == true) {
994 if (scoreboard->getReg(renamed_reg)) {
986 DPRINTF(Rename, "[tid:%u]: Register %d is ready.\n",
987 tid, renamed_reg);
988
989 inst->markSrcRegReady(src_idx);
990 } else {
991 DPRINTF(Rename, "[tid:%u]: Register %d is not ready.\n",
992 tid, renamed_reg);
993 }
994
995 ++renameRenameLookups;
995 DPRINTF(Rename, "[tid:%u]: Register %d is ready.\n",
996 tid, renamed_reg);
997
998 inst->markSrcRegReady(src_idx);
999 } else {
1000 DPRINTF(Rename, "[tid:%u]: Register %d is not ready.\n",
1001 tid, renamed_reg);
1002 }
1003
1004 ++renameRenameLookups;
996 inst->isFloating() ? fpRenameLookups++ : intRenameLookups++;
997 }
998}
999
1000template <class Impl>
1001inline void
1002DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
1003{
1005 }
1006}
1007
1008template <class Impl>
1009inline void
1010DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
1011{
1004 typename RenameMap::RenameInfo rename_result;
1005
1012 ThreadContext *tc = inst->tcBase();
1013 RenameMap *map = renameMap[tid];
1006 unsigned num_dest_regs = inst->numDestRegs();
1007
1008 // Rename the destination registers.
1009 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
1010 RegIndex dest_reg = inst->destRegIdx(dest_idx);
1014 unsigned num_dest_regs = inst->numDestRegs();
1015
1016 // Rename the destination registers.
1017 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
1018 RegIndex dest_reg = inst->destRegIdx(dest_idx);
1011 RegIndex flat_dest_reg = dest_reg;
1012 switch (regIdxToClass(dest_reg)) {
1019 RegIndex rel_dest_reg;
1020 RegIndex flat_rel_dest_reg;
1021 RegIndex flat_uni_dest_reg;
1022 typename RenameMap::RenameInfo rename_result;
1023
1024 switch (regIdxToClass(dest_reg, &rel_dest_reg)) {
1013 case IntRegClass:
1025 case IntRegClass:
1014 // Integer registers are flattened.
1015 flat_dest_reg = inst->tcBase()->flattenIntIndex(dest_reg);
1016 DPRINTF(Rename, "Flattening index %d to %d.\n",
1017 (int)dest_reg, (int)flat_dest_reg);
1026 flat_rel_dest_reg = tc->flattenIntIndex(rel_dest_reg);
1027 rename_result = map->renameInt(flat_rel_dest_reg);
1028 flat_uni_dest_reg = flat_rel_dest_reg; // 1:1 mapping
1018 break;
1019
1020 case FloatRegClass:
1029 break;
1030
1031 case FloatRegClass:
1021 dest_reg = dest_reg - TheISA::FP_Reg_Base;
1022 flat_dest_reg = inst->tcBase()->flattenFloatIndex(dest_reg);
1023 DPRINTF(Rename, "Flattening index %d to %d.\n",
1024 (int)dest_reg, (int)flat_dest_reg);
1025 flat_dest_reg += TheISA::NumIntRegs;
1032 flat_rel_dest_reg = tc->flattenFloatIndex(rel_dest_reg);
1033 rename_result = map->renameFloat(flat_rel_dest_reg);
1034 flat_uni_dest_reg = flat_rel_dest_reg + TheISA::FP_Reg_Base;
1026 break;
1027
1028 case MiscRegClass:
1035 break;
1036
1037 case MiscRegClass:
1029 // Floating point and Miscellaneous registers need their indexes
1030 // adjusted to account for the expanded number of flattened int regs.
1031 flat_dest_reg = dest_reg - TheISA::Misc_Reg_Base +
1032 TheISA::NumIntRegs + TheISA::NumFloatRegs;
1033 DPRINTF(Rename, "Adjusting reg index from %d to %d.\n",
1034 dest_reg, flat_dest_reg);
1038 // misc regs don't get flattened
1039 flat_rel_dest_reg = rel_dest_reg;
1040 rename_result = map->renameMisc(flat_rel_dest_reg);
1041 flat_uni_dest_reg = flat_rel_dest_reg + TheISA::Misc_Reg_Base;
1035 break;
1036
1037 default:
1038 panic("Reg index is out of bound: %d.", dest_reg);
1039 }
1040
1042 break;
1043
1044 default:
1045 panic("Reg index is out of bound: %d.", dest_reg);
1046 }
1047
1041 inst->flattenDestReg(dest_idx, flat_dest_reg);
1048 inst->flattenDestReg(dest_idx, flat_uni_dest_reg);
1042
1049
1043 // Get the physical register that the destination will be
1044 // renamed to.
1045 rename_result = renameMap[tid]->rename(flat_dest_reg);
1046
1047 //Mark Scoreboard entry as not ready
1050 // Mark Scoreboard entry as not ready
1048 scoreboard->unsetReg(rename_result.first);
1049
1050 DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
1051 scoreboard->unsetReg(rename_result.first);
1052
1053 DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
1051 "reg %i.\n", tid, (int)flat_dest_reg,
1054 "reg %i.\n", tid, (int)flat_rel_dest_reg,
1052 (int)rename_result.first);
1053
1054 // Record the rename information so that a history can be kept.
1055 (int)rename_result.first);
1056
1057 // Record the rename information so that a history can be kept.
1055 RenameHistory hb_entry(inst->seqNum, flat_dest_reg,
1058 RenameHistory hb_entry(inst->seqNum, flat_uni_dest_reg,
1056 rename_result.first,
1057 rename_result.second);
1058
1059 historyBuffer[tid].push_front(hb_entry);
1060
1061 DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer "
1062 "(size=%i), [sn:%lli].\n",tid,
1063 historyBuffer[tid].size(),

--- 310 unchanged lines hidden ---
1059 rename_result.first,
1060 rename_result.second);
1061
1062 historyBuffer[tid].push_front(hb_entry);
1063
1064 DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer "
1065 "(size=%i), [sn:%lli].\n",tid,
1066 historyBuffer[tid].size(),

--- 310 unchanged lines hidden ---