專利名稱:終極管道和最優(yōu)重排技術(shù)的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及一種二進(jìn)制代碼轉(zhuǎn)換器,該代碼轉(zhuǎn)換器用于將遺留處理器的二進(jìn)制代碼直接轉(zhuǎn)換為本機(jī)處理器可執(zhí)行的二進(jìn)制代碼,并且更加具體地講,涉及一種形成為可重新配置的代碼轉(zhuǎn)換器的二進(jìn)制代碼轉(zhuǎn)換器,這適合于用于不同的遺留處理器和/或操作系統(tǒng)以及不同的本機(jī)處理器,在該轉(zhuǎn)換器中可對遺留代碼進(jìn)行靜態(tài)轉(zhuǎn)換、動(dòng)態(tài)轉(zhuǎn)換或即時(shí)轉(zhuǎn)換,并且允許插入新的代碼或禁用部分遺留代碼,而不對遺留二進(jìn)制代碼進(jìn)行修改。
背景技術(shù):
我們都知道,微處理器是利用不同的指令系統(tǒng)體系結(jié)構(gòu)(ISA)配置的。ISA為具體的微處理器確定了指令系統(tǒng)。由微處理器執(zhí)行的應(yīng)用程序通常是用稱作源代碼的相對高級語言寫成的,例如用C或C++,并將這些應(yīng)用程序編譯為與具體的微處理器的指令系統(tǒng)相符的機(jī)器指令。這些機(jī)器指令稱為二進(jìn)制代碼、目標(biāo)碼和可執(zhí)行代碼。
歸因于許多現(xiàn)有微處理器的老化和陳舊以及它們相應(yīng)的低速度,經(jīng)常需要用更新更快的微處理器(這里稱為“本機(jī)微處理器”或“本機(jī)處理器”)來更換過時(shí)的現(xiàn)有微處理器(下文中稱為“遺留微處理器”和“遺留處理器”)??上?,依靠于升級,本機(jī)處理器的指令系統(tǒng)時(shí)常與遺留處理器的指令系統(tǒng)不兼容。同樣地,已經(jīng)開發(fā)出了多種多樣的使針對遺留處理器編寫的應(yīng)用程序能夠在更新的本機(jī)處理器上應(yīng)用的技術(shù)。例如,我們已經(jīng)知道的軟件仿真程序。這種軟件仿真程序是建立在對應(yīng)用程序中所使用的遺留處理器的各種機(jī)器代碼指令進(jìn)行仿真的基礎(chǔ)上的。我們知道這樣的仿真器包括多個(gè)由一個(gè)或多個(gè)本機(jī)指令組成以實(shí)現(xiàn)與所仿真的遺留指令相同的功能的軟件處理程序。在共同擁有的美國專利第6041402號、第6212614號和第6272453號以及2003年3月6日申請(摘要第20-0169號)的名稱為《直接指令翻譯仿真計(jì)算機(jī)技術(shù)(Direct Instruction Rendering Emulation ComputerTechnique)》的共同擁有的美國專利申請序列號第__號中,公開了這樣的指令仿真程序系統(tǒng)的實(shí)例。
還有一些原因表明了為什么需要二進(jìn)制代碼轉(zhuǎn)換器。首先,可能無法利用遺留源代碼向現(xiàn)代計(jì)算機(jī)體系結(jié)構(gòu)實(shí)現(xiàn)軟件移植。其次,與傳統(tǒng)的仿真系統(tǒng)相關(guān)的軟件系統(tǒng)開銷顯著地減緩了處理速度。于是,對于遺留代碼在更新的、不兼容的硬件平臺上的再使用來說,二進(jìn)制代碼轉(zhuǎn)換是唯一可行的選擇。
這種二進(jìn)制代碼轉(zhuǎn)換器將遺留處理器的二進(jìn)制代碼直接轉(zhuǎn)換為本機(jī)處理器的二進(jìn)制代碼。在美國專利第6223339號、第6314560號和第6502237號中公開了這種二進(jìn)制代碼轉(zhuǎn)換器的例子。而且在于1997年2月23日-26日在加利福尼亞圣何塞召開的97年計(jì)算機(jī)會議論文集(Compcon’97 proceedings,IEEE)中的第37-42頁的由數(shù)字設(shè)備公司(Digital Equipment Corporation)的R.Hookway所著的《在Alpha NT上運(yùn)行32位x86應(yīng)用程序的DIGITAL FX!32(DIGITAL FX!32 Runningon 32-bit x86 Application on Alpha NT)》、2001年11月出版的IEEE學(xué)報(bào)第11期第89卷第1710-1722頁中的Altman等人所著的《二進(jìn)制代碼轉(zhuǎn)換及優(yōu)化進(jìn)展與未來前景(Advances and Future Chanllenges inBinary Translation and Optimization)》、數(shù)字技術(shù)雜志(Digital TechnicalJournal)1997年第1期第9卷第1-12頁中的由Hookway等人所著的《數(shù)字FX!32仿真與二進(jìn)制代碼轉(zhuǎn)換的結(jié)合(Digital FX!32CombiningEmulation and Binary Translation)》、計(jì)算機(jī)雜志(Computer Magazine)2000年3月第33卷第47-52頁上的由Zheng等人所著的《PA-RISC到IA-64透明執(zhí)行,無需再編譯(PA-RISC to IA-64TransparentExecution,No Recompilation)》這些文獻(xiàn)中也公開了二進(jìn)制代碼轉(zhuǎn)換器。
雖然已知的二進(jìn)制代碼轉(zhuǎn)換器能夠?qū)⑦z留二進(jìn)制代碼有效地轉(zhuǎn)換為本機(jī)二進(jìn)制代碼而無需修改遺留二進(jìn)制代碼,但是卻存在著與這些已知的二進(jìn)制代碼轉(zhuǎn)換器相關(guān)的問題。例如,絕大多數(shù)二進(jìn)制代碼轉(zhuǎn)換器都是為單一的遺留/本機(jī)處理器和操作系統(tǒng)的組合而開發(fā)的。因此,在不同的遺留處理器和/或本機(jī)處理器上運(yùn)行的應(yīng)用程序?qū)⑿枰獑为?dú)的代碼轉(zhuǎn)換器。此外,這些已知代碼轉(zhuǎn)換器不允許為了實(shí)現(xiàn)禁用部分遺留代碼或無需重新編譯程序地對其進(jìn)行增強(qiáng)的目的而添加用現(xiàn)代程序設(shè)計(jì)語言編寫的新本機(jī)代碼,這要求有權(quán)使用原始源代碼。因此,存在著對適用于多種遺留處理器和本機(jī)處理器和/或操作系統(tǒng)并且在遺留和本機(jī)指令層面上都可以進(jìn)行模塊化優(yōu)化同時(shí)允許無需重新編譯遺留程序地添加新的本機(jī)代碼的一種用于將遺留二進(jìn)制指令轉(zhuǎn)換為本機(jī)指令的二進(jìn)制代碼轉(zhuǎn)換器的需求。
發(fā)明內(nèi)容
本發(fā)明涉及一種用于將針對遺留處理器編寫的二進(jìn)制指令直接轉(zhuǎn)換為本機(jī)處理器可執(zhí)行的二進(jìn)制指令的二進(jìn)制代碼轉(zhuǎn)換器。按照本發(fā)明的一個(gè)重要方面,所述二進(jìn)制代碼轉(zhuǎn)換器是一種可重新配置的代碼轉(zhuǎn)換器,這使得該二進(jìn)制代碼轉(zhuǎn)換器能夠用于遺留處理器和/或操作系統(tǒng)以及本機(jī)處理器的不同組合。還對該二進(jìn)制代碼轉(zhuǎn)換器進(jìn)行優(yōu)化,以利用更有效的本機(jī)處理器指令和可用功能,并允許禁用部分遺留二進(jìn)制代碼和/或?qū)⑿碌谋緳C(jī)指令加入到應(yīng)用程序中而無需改變遺留二進(jìn)制代碼。
參照后面的說明和所附的附圖,將會更加容易地理解本發(fā)明的這些和其它的優(yōu)點(diǎn),其中附圖1是一個(gè)示范性軟件模型的框圖,它說明了應(yīng)用程序是如何與系統(tǒng)操作系統(tǒng)和處理器相互作用的。
附圖2是一個(gè)框圖,它說明了按照本發(fā)明的一個(gè)方面的用于將二進(jìn)制指令插入到本機(jī)指令組中的thunk過程。
附圖3是按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器的框圖,對其各個(gè)子系統(tǒng)進(jìn)行了說明。
附圖4是為了在運(yùn)行Linux操作系統(tǒng)的本機(jī)Intel IA-64處理器上使用而用于對針對Tru64 Unix操作系統(tǒng)編寫的示范性遺留Alpha 21264微處理器應(yīng)用程序進(jìn)行轉(zhuǎn)換的示范性載入程序程序表。
附圖5是表示示范性遺留代碼段和向量空間之間的關(guān)系的示范性存儲器分配圖。
附圖6是表示用于按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器的存儲器配置的示范性示意圖。
附圖7是用于按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器的類圖。
附圖8是用于按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器的分級類圖。
附圖9是按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器的過程圖。
附圖10是按照本發(fā)明的用于IA-64微處理器的調(diào)度優(yōu)化程序的框圖。
附圖11是按照本發(fā)明的示范性指令調(diào)度優(yōu)化程序算法的流程圖。
附圖12是表示Alpha遺留二進(jìn)制指令到Intel IA-64本機(jī)處理器二進(jìn)制指令的示范性指令轉(zhuǎn)換的框圖。
附圖13表示用于Intel IA-64本機(jī)處理器的指令束格式。
附圖14表示一個(gè)標(biāo)準(zhǔn)型Itanium 2處理器的執(zhí)行單元格式。
附圖15表示如何將兩個(gè)IA-64指令組中的第一個(gè)中的經(jīng)轉(zhuǎn)換的IA-64本機(jī)處理器指令組織為IA-64指令束。
附圖16與附圖15相類似,只是表示對兩個(gè)IA-64指令組中的第二個(gè)的處理過程。
附圖17表示按照本發(fā)明的轉(zhuǎn)移判定優(yōu)化方法實(shí)例。
具體實(shí)施例方式
本發(fā)明涉及一種形成為可重新配置的代碼轉(zhuǎn)換器的二進(jìn)制代碼轉(zhuǎn)換器,該代碼轉(zhuǎn)換器能夠?qū)⑦z留微處理器的二進(jìn)制指令直接轉(zhuǎn)換為本機(jī)處理器的二進(jìn)制指令。遺留處理器的二進(jìn)制指令的直接轉(zhuǎn)換得到本機(jī)二進(jìn)制指令,這樣通常要比對遺留指令進(jìn)行仿真執(zhí)行起來快得多。此外,依照本發(fā)明的一個(gè)重要方面,能夠?qū)υ撓到y(tǒng)進(jìn)行配置以應(yīng)用于多種本機(jī)處理器、多種遺留處理器和操作系統(tǒng)。為了進(jìn)一步提高經(jīng)轉(zhuǎn)換的本機(jī)程序的適應(yīng)性,可以使用thunk對象來禁用部分遺留二進(jìn)制指令和/或插入新的本機(jī)指令而無需改變原始的遺留二進(jìn)制代碼。如后面將要詳細(xì)討論的,按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器是這樣將遺留二進(jìn)制代碼轉(zhuǎn)換為本機(jī)二進(jìn)制指令的首先將遺留二進(jìn)制指令分組為連續(xù)執(zhí)行的代碼段、實(shí)施算法優(yōu)化,然后將這些二進(jìn)制指令一條一條地轉(zhuǎn)換為本機(jī)指令系統(tǒng)。一旦完成了指令轉(zhuǎn)換,如果需要的話,還可以執(zhí)行本機(jī)優(yōu)化程序。取決于本機(jī)處理器,可以對本機(jī)二進(jìn)制指令進(jìn)行重排和/或分組,以充分利用可用的處理器資源。所得到的本機(jī)二進(jìn)制指令因此能夠在本機(jī)平臺上獨(dú)立執(zhí)行。
按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器是以三種不同的工作模式進(jìn)行工作的靜態(tài)轉(zhuǎn)換模式,在該模式下,脫機(jī)地完成轉(zhuǎn)換以生成新的可執(zhí)行本機(jī)指令的二進(jìn)制代碼;動(dòng)態(tài)轉(zhuǎn)換模式,在該模式下,轉(zhuǎn)換是在將遺留二進(jìn)制代碼載入本機(jī)處理器存儲器中的同時(shí)進(jìn)行的;還有一種即時(shí)轉(zhuǎn)換模式,在該模式下,當(dāng)且僅當(dāng)首次執(zhí)行遺留指令需要對他們進(jìn)行轉(zhuǎn)換的時(shí)候才對這些遺留二進(jìn)制指令進(jìn)行轉(zhuǎn)換。
雖然將按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器形成為可重新配置的代碼轉(zhuǎn)換器,其可以為了用于各種遺留的和本機(jī)的處理器而進(jìn)行配置,但是本發(fā)明的示范性實(shí)施例是一個(gè)使用Tru64 Unix操作系統(tǒng)的Alpha21264微處理器和一個(gè)使用Linux操作系統(tǒng)的Intel IA-64本機(jī)處理器。該Alpha 21264微處理器是一個(gè)精簡指令系統(tǒng)計(jì)算機(jī)(RISC)。使用RISC體系結(jié)構(gòu)配置的微處理器一般在寄存器中執(zhí)行所有的指令。載入和存儲指令用于將數(shù)據(jù)取入寄存器和將結(jié)果保存回存儲器中。出于這一原因,RISC體系結(jié)構(gòu)被稱為“載入/存儲”體系結(jié)構(gòu)。RISC體系結(jié)構(gòu)還排除了復(fù)雜的指令,以降低硬件的復(fù)雜程度?,F(xiàn)代軟件設(shè)計(jì)模式促進(jìn)了高級語言的使用并且編譯器一般不使用復(fù)雜的指令。
所述Intel IA-64微處理器采用了一種相對較新的設(shè)計(jì)模式,稱為顯性并行指令計(jì)算機(jī)(EPIC)。這種EPIC體系結(jié)構(gòu)規(guī)定用于最佳性能的調(diào)度指令是由編譯器(或匯編語言編程器)完成的,而不是微處理器硬件。IA-64采用了一些功能部件來消除或減小處理器性能問題的范圍。例如,這種IA-64處理器包含有相對較大的寄存器組;消除短正向轉(zhuǎn)移的能力;以及相對較大的執(zhí)行單元數(shù)量,以提高并行代碼執(zhí)行能力。該IA-64微處理器包括一個(gè)不斷壯大的微處理器家族。下面的說明涉及一種稱為Itanium 2的標(biāo)準(zhǔn)型IA-64處理器。
應(yīng)用軟件模型參照附圖1,示出了一個(gè)現(xiàn)代軟件應(yīng)用系統(tǒng)的層次模型。該模型包括一個(gè)應(yīng)用軟件層20、一個(gè)系統(tǒng)程序庫層22、一個(gè)操作系統(tǒng)層24和一個(gè)硬件層26?,F(xiàn)代軟件應(yīng)用系統(tǒng)程序20通常是為了在特定的微處理器體系結(jié)構(gòu)和操作系統(tǒng)上運(yùn)行而編寫的。如圖所示,應(yīng)用軟件20利用微處理器操作系統(tǒng)24的服務(wù)程序以及一組系統(tǒng)程序庫22來執(zhí)行通用任務(wù)。具體來說,該應(yīng)用軟件可以直接請求操作系統(tǒng)調(diào)用,如箭頭28所示,不過更一般地是借助系統(tǒng)程序庫調(diào)用與系統(tǒng)程序庫22進(jìn)行聯(lián)系,如箭頭30所示。順次地,系統(tǒng)程序庫22典型地向操作系統(tǒng)層24請求系統(tǒng)調(diào)用,如箭頭32所示。例如,標(biāo)準(zhǔn)C/C++系統(tǒng)程序庫層22包含利用C函數(shù)處理磁盤文件的能力。這些函數(shù)依次地通過系統(tǒng)調(diào)用與操作系統(tǒng)相互作用。如下面將要詳細(xì)討論的,按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器與底層操作系統(tǒng)發(fā)生聯(lián)系而不需要與遺留和本機(jī)操作系統(tǒng)發(fā)生聯(lián)系。
二進(jìn)制代碼轉(zhuǎn)換器子系統(tǒng)參照附圖3,按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器是由四個(gè)模塊化的且可重新配置的子系統(tǒng)組成的一個(gè)裝入程序子系統(tǒng)34、一個(gè)遺留指令處理程序子系統(tǒng)36、指令轉(zhuǎn)換器子系統(tǒng)38和一個(gè)本機(jī)指令處理程序子系統(tǒng)40。每個(gè)子系統(tǒng)34、36、38和40都是例如用C++寫成的模塊化對象。照此,任何一個(gè)子系統(tǒng)34、36、38和40都可以圍繞一個(gè)具體的本機(jī)處理器體系結(jié)構(gòu)、一個(gè)遺留處理器體系結(jié)構(gòu)或者二者全部來進(jìn)行設(shè)計(jì)。照此,按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器是可重新配置的,就是說它可針對任何遺留的或本機(jī)處理器而進(jìn)行配置,而不象公知的二進(jìn)制代碼轉(zhuǎn)換器那樣是針對一個(gè)具體的遺留/本機(jī)處理器組合而配置的。
后面將給出每個(gè)子系統(tǒng)的詳細(xì)討論。不過,總地來說,所述載入程序34從遺留二進(jìn)制文件中讀取遺留代碼和數(shù)據(jù)段。所述遺留指令處理程序子系統(tǒng)36對這些遺留指令加以分類并將遺留程序分解為遺留進(jìn)程。此外,如果存在任何轉(zhuǎn)換前優(yōu)化模塊并且它們是有效的,那么將會對它們進(jìn)行調(diào)用。所述指令轉(zhuǎn)換器子系統(tǒng)38將那些遺留指令轉(zhuǎn)換為本機(jī)指令。所述本機(jī)指令處理程序子系統(tǒng)40調(diào)用轉(zhuǎn)換后優(yōu)化模塊,如果有這樣的模塊的話,并將所得到的完全轉(zhuǎn)換的程序?qū)懭氡緳C(jī)處理器存儲器或磁盤文件中,以進(jìn)行后續(xù)運(yùn)行。
按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器另外還允許將代碼優(yōu)化模塊插入到子系統(tǒng)36或40中,以進(jìn)一步提高系統(tǒng)性能。參照附圖9,這些模塊由附圖標(biāo)記64和66標(biāo)示??梢源嬖谌我鈹?shù)量的優(yōu)化模塊,它們可以對轉(zhuǎn)換前遺留代碼、轉(zhuǎn)換后遺留代碼或它們的某種組合進(jìn)行操作。如果需要,也可以除去這些優(yōu)化模塊。
按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器還考慮到了將新的本機(jī)代碼插入到轉(zhuǎn)換后的遺留代碼流中。這些新的本機(jī)代碼字段稱為“thunk”。附圖2中示出了一個(gè)thunk 42。這些thunk對象42可用于為了實(shí)現(xiàn)各種目的而增加功能,而無需改變已有的二進(jìn)制代碼,例如增加新的功能或禁用部分原始的遺留代碼。如附圖2所示,示出了三個(gè)本機(jī)指令組塊44、46和48。Thunk代碼是借助從本機(jī)指令代碼44指向thunk對象42的向量插入的。執(zhí)行thunk對象42中的thunk代碼。一旦完成了thunk代碼的執(zhí)行,如附圖2所示,系統(tǒng)引導(dǎo)返回到本機(jī)指令組。
載入程序子系統(tǒng)如上面所提到的,所述載入程序子系統(tǒng)34讀取遺留二進(jìn)制文件并提取遺留代碼和數(shù)據(jù)段。該載入程序子系統(tǒng)34是一個(gè)可插入系統(tǒng),它能夠適用于多種文件格式。對于上面所提到的示范性遺留處理器和操作系統(tǒng)來說,示范性的載入程序包括Linux可執(zhí)行和連接格式(ELF)和Tru64 Unix公用對象文件格式(COFF)。
所述載入程序子系統(tǒng)34僅通過少數(shù)幾個(gè)接口程序與二進(jìn)制代碼轉(zhuǎn)換器的平衡進(jìn)行聯(lián)系。附圖4表示在對使用Tru64操作系統(tǒng)的Alpha遺留微處理器的指令到使用Linux操作系統(tǒng)的Intel IA-64微處理器的轉(zhuǎn)換中所使用的一個(gè)示范性的通用建模語言(UML)程序表。
遺留指令處理程序子系統(tǒng)所述遺留指令處理程序子系統(tǒng)36對遺留指令進(jìn)行分析、按照它們的一般職能確定它們的類型并將這些指令分解為遺留代碼的功能塊。在遺留指令處理程序子系統(tǒng)36失去控制權(quán)之前,它能夠調(diào)用任何所需的可用的且有活性的遺留優(yōu)化程序。遺留指令處理程序子系統(tǒng)36獨(dú)立于運(yùn)行著系統(tǒng)的本機(jī)處理器。
遺留指令處理程序子系統(tǒng)36將遺留程序分解為多個(gè)段,稱為遺留進(jìn)程。一個(gè)遺留進(jìn)程是一段以遺留流程控制指令結(jié)束的遺留指令,例如轉(zhuǎn)移指令。每個(gè)遺留指令被放置在一個(gè)container對象中,稱為“LegacyInstruction”。該LegacyInstruction對象保存在“LegacyProcedure”對象中。如后面將要詳細(xì)討論的,在靠后的階段中,將把“NativeInstruction”添加到LegacyProcedure對象中。
每個(gè)LegacyInstruction對象含有遺留二進(jìn)制指令以及關(guān)于該指令的信息,該信息包括其總體類型以及如何將其轉(zhuǎn)換為本機(jī)處理器指令。然后container對象可用于在轉(zhuǎn)換和優(yōu)化中所使用的其它子系統(tǒng)。所有的遺留進(jìn)程對象都包含在一個(gè)LegacyProgram對象中。
遺留指令處理程序36是一個(gè)模塊化子系統(tǒng)并且將其配置得與不同的遺留處理器實(shí)現(xiàn)兼容。這可以通過C++對象定向技術(shù)來實(shí)現(xiàn)。存在基本類以定義所需的接口程序。
在對遺留指令進(jìn)行了分組和確定了類型之后,遺留處理程序子系統(tǒng)36在退出之前調(diào)用任意所需的轉(zhuǎn)換前優(yōu)化模塊并且有許多的優(yōu)化模塊可供選擇執(zhí)行。轉(zhuǎn)換前優(yōu)化模塊對遺留指令起作用并且可以禁用它們,擴(kuò)充它們,或者與轉(zhuǎn)換后優(yōu)化程序相結(jié)合產(chǎn)生更好的執(zhí)行代碼。
指令轉(zhuǎn)換器子系統(tǒng)所述指令轉(zhuǎn)換器子系統(tǒng)38進(jìn)行從遺留處理器指令到本機(jī)處理器指令的轉(zhuǎn)換。該子系統(tǒng)38依賴于遺留和本機(jī)處理器體系結(jié)構(gòu)。該子系統(tǒng)38是由其它子系統(tǒng)進(jìn)行調(diào)用的,并且含有執(zhí)行如下所述的兩個(gè)主要功能的指令轉(zhuǎn)換對象●指令類型確定。遺留指令處理程序36使用指令類型確定判定遺留指令的類型。這種結(jié)構(gòu)方式指示遺留指令處理程序此時(shí)它遇到了一個(gè)遺留流程控制指令并且提供轉(zhuǎn)換前優(yōu)化程序可能需要的類型信息。
●指令轉(zhuǎn)換。本機(jī)指令處理程序子系統(tǒng)36使用這一服務(wù)來產(chǎn)生執(zhí)行遺留指令所要求的操作的本機(jī)處理器指令。
所述指令轉(zhuǎn)換器子系統(tǒng)38最終負(fù)責(zé)執(zhí)行所有的遺留到本機(jī)的指令轉(zhuǎn)換。
在本發(fā)明的一個(gè)示范性的實(shí)施例中,其中將Alpha遺留微處理器的二進(jìn)制指令轉(zhuǎn)換為用于Intel IA-64微處理器的適當(dāng)?shù)亩M(jìn)制指令,該指令轉(zhuǎn)換器子系統(tǒng)38可以由一系列的C函數(shù)實(shí)現(xiàn)-每一個(gè)函數(shù)對應(yīng)于各個(gè)Alpha遺留指令來產(chǎn)生所需的IA-64本機(jī)處理器指令。這些C函數(shù)此后稱為遺留指令轉(zhuǎn)換器。另外,一系列的C函數(shù),每一個(gè)函數(shù)對應(yīng)于一個(gè)所需的IA-64遺留本機(jī)處理器指令,可以從所述遺留指令轉(zhuǎn)換器內(nèi)部使用。這些C函數(shù)下文中稱為本機(jī)指令發(fā)生器。
本機(jī)指令處理程序子系統(tǒng)所述本機(jī)指令處理程序子系統(tǒng)40請求遺留指令到本機(jī)指令的轉(zhuǎn)換、調(diào)用任何需要的本機(jī)指令優(yōu)化模塊并將經(jīng)轉(zhuǎn)換的二進(jìn)制代碼寫入到本機(jī)處理器存儲器或一個(gè)文件中以備今后使用。
本機(jī)指令對象用于保存重復(fù)遺留進(jìn)程的行為所需的本機(jī)指令。一個(gè)遺留進(jìn)程所需的本機(jī)指令對象的數(shù)量可以與或不與遺留指令對象的數(shù)量相匹配,這是因?yàn)橹貜?fù)遺留指令的行為所需的本機(jī)指令的數(shù)量是變化的。所有的本機(jī)指令對象,作為一個(gè)整體,是經(jīng)轉(zhuǎn)換的二進(jìn)制程序的指令部分。
本機(jī)指令處理程序子系統(tǒng)40完全可配置為能夠使遺留二進(jìn)制指令在各種各樣不同的本機(jī)處理器上執(zhí)行的子系統(tǒng)。這個(gè)子系統(tǒng)40獨(dú)立于正在使用的遺留處理器工作。
如前面所提到的,借助指令轉(zhuǎn)換器子系統(tǒng)38進(jìn)行的指令轉(zhuǎn)換是由本機(jī)指令處理程序子系統(tǒng)40調(diào)用的。這一過程包括將一定數(shù)量的本機(jī)指令對象加入到已經(jīng)產(chǎn)生的遺留進(jìn)程對象中,這些本機(jī)指令對象含有經(jīng)轉(zhuǎn)換的主處理器指令。此時(shí)本機(jī)指令沒有提交給存儲器或文件,這是因?yàn)檗D(zhuǎn)換后優(yōu)化程序可能會改變本機(jī)指令組合。
在每個(gè)遺留指令都已經(jīng)轉(zhuǎn)換為一個(gè)或多個(gè)本機(jī)處理器指令之后,將調(diào)用所存在的任意轉(zhuǎn)換后優(yōu)化程序。這些可插入模塊可能是激活的或停用的。
轉(zhuǎn)換過程如上面所提到的,將遺留程序分解為由遺留流程控制指令結(jié)束的遺留進(jìn)程。這允許同時(shí)對多個(gè)指令進(jìn)行處理,以得到較佳優(yōu)化的代碼。例如,Intel IA-64體系結(jié)構(gòu)每時(shí)鐘周期允許執(zhí)行多達(dá)六條指令。同時(shí)處理多個(gè)指令允許根據(jù)數(shù)據(jù)相關(guān)性判斷哪些指令對于并行執(zhí)行是安全的。結(jié)果,為遺留指令字段或進(jìn)程生成的那些本機(jī)指令可以不執(zhí)行與遺留處理器順序完全相同的操作。不過,只要考慮到了數(shù)據(jù)相關(guān)性,這就并不成其為問題了。然而,一次一條地執(zhí)行Intel IA-64指令,是無法充分利用該處理器的運(yùn)行資源的。
按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器使用一個(gè)向量表或向量空間,其含有與每條遺留指令相對應(yīng)的64位值。這些64位值是用于每條指令的本機(jī)指令處理程序的完整地址。不過,并不是每條指令都含有一個(gè)有效的向量條目,這是由于遺留指令均被分解為以遺留流程控制指令結(jié)束的遺留代碼字段。由于按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器是以連續(xù)執(zhí)行遺留代碼塊或字段的方式工作的,因此僅僅每個(gè)相應(yīng)的遺留代碼字段(或遺留進(jìn)程)的開端需要一個(gè)向量。該向量就是用于某個(gè)進(jìn)程的本機(jī)指令處理程序的地址。例如,附圖5表示由附圖標(biāo)記50和52標(biāo)出的兩組遺留指令及其地址。每組指令50、52以一個(gè)轉(zhuǎn)移指令BEQ結(jié)束,它們組成了一個(gè)遺留代碼字段(或遺留進(jìn)程)。每個(gè)遺留地址在所述向量空間中具有一個(gè)相應(yīng)的位置。依次地,每個(gè)在所述向量空間中占有一席之地的條目都指向微碼空間中的一個(gè)本機(jī)指令處理程序。按照本發(fā)明的一個(gè)方面,在處理轉(zhuǎn)移指令的時(shí)候,二進(jìn)制代碼轉(zhuǎn)換器使用一個(gè)雙處理周期轉(zhuǎn)換系統(tǒng)。更具體地講,對于許多遺留轉(zhuǎn)移指令來說,直接從遺留代碼中確定轉(zhuǎn)移目的地是可能的。而另外一些情況下,目的地代碼是無法直接確定的。按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器對這兩種情況均能處理。
轉(zhuǎn)換的第一個(gè)處理周期為所有遺留指令產(chǎn)生本機(jī)指令,只是除了跳轉(zhuǎn)或轉(zhuǎn)移指令(即流程控制指令)。一旦完成了第一個(gè)處理周期,就可以完成相關(guān)的轉(zhuǎn)移指令的轉(zhuǎn)換了,這是由于其余的代碼都已經(jīng)產(chǎn)生了。第二個(gè)處理周期為那些目的地可以在轉(zhuǎn)換的時(shí)候得到確定的轉(zhuǎn)移填補(bǔ)轉(zhuǎn)移指令。
如果可以在轉(zhuǎn)換的時(shí)候確定轉(zhuǎn)移目的地并且該轉(zhuǎn)移指向一個(gè)沒有有效向量的位置的話,則產(chǎn)生一個(gè)LegacyProcedure對象并從那一點(diǎn)開始向前裝入遺留指令直到找到遺留流程控制指令。例如,參照附圖5,如果一個(gè)已結(jié)束的轉(zhuǎn)移轉(zhuǎn)到位置1020,則將會產(chǎn)生一個(gè)LegacyProcedure對象并且該對象會為位于地址1020、1024和1028的指令進(jìn)行轉(zhuǎn)換。這一處理是在第二個(gè)處理周期期間發(fā)生的。因此,該第二個(gè)處理周期為載入時(shí)獲知的目的地完成了所有轉(zhuǎn)移指令并且為還不具有有效向量的目的地建立了新的處理器。
雖然所述雙處理周期轉(zhuǎn)換能夠處理許多轉(zhuǎn)移指令,但是在載入時(shí)并不是所有的轉(zhuǎn)移目的地都得以獲知。某些轉(zhuǎn)移指令依賴于運(yùn)行時(shí)計(jì)算出來的目的地地址。在這些情況下,這些轉(zhuǎn)移指令從向量空間中獲取它們的本機(jī)指令處理程序地址并跳轉(zhuǎn)到這些位置。如果沒有針對該目的地的有效向量,則動(dòng)態(tài)地產(chǎn)生一個(gè)本機(jī)指令處理程序并且將其地址加入到所述向量空間中。這一過程是借助動(dòng)態(tài)嘗試來完成的,所述動(dòng)態(tài)嘗試從轉(zhuǎn)移目的地地址開始并連續(xù)進(jìn)行遺留代碼的運(yùn)行同步轉(zhuǎn)換,直到找到一個(gè)遺留流程控制指令。該動(dòng)態(tài)嘗試對象建立一個(gè)新的LegacyProcedure對象并將用于遺留指令的LegacyInstruction對象裝入其中,直到下一個(gè)流程控制指令。然后它請求遺留指令的轉(zhuǎn)換并將所得到的本機(jī)指令提交給存儲器。這個(gè)系統(tǒng)能夠處理所有的轉(zhuǎn)移指令,但是由于進(jìn)行轉(zhuǎn)移目的地的預(yù)計(jì)算能夠?qū)崿F(xiàn)更好的性能,所以該系統(tǒng)只是用作最后使用的手段。
操作系統(tǒng)調(diào)用如上面所提到的,我們知道應(yīng)用程序是通過系統(tǒng)程序庫函數(shù)直接地或間接地進(jìn)行操作系統(tǒng)調(diào)用的。例如,Alpha 21264微處理器體系結(jié)構(gòu)將系統(tǒng)調(diào)用定義為一種特定指令。該指令在執(zhí)行的時(shí)候引發(fā)一個(gè)操作系統(tǒng)中斷。在系統(tǒng)調(diào)用指令之前,編譯器和/或編程器必須將系統(tǒng)調(diào)用號插入到一個(gè)已知的寄存器中,在Alpha 21264微處理器的情況中是$v0。系統(tǒng)調(diào)用號從$v0中提取出來并且其它的參數(shù)可以從按照系統(tǒng)的函數(shù)調(diào)用慣用手段定義的其它寄存器中提取出來。對于二進(jìn)制代碼轉(zhuǎn)換器而言,系統(tǒng)調(diào)用僅僅是另一個(gè)指令而已。不過操作系統(tǒng)之間的系統(tǒng)調(diào)用號可以是也確實(shí)是不同的。舉例來說,OpenVMS操作系統(tǒng)與Tru64 Unix就使用了不同的系統(tǒng)調(diào)用號。用于Alpha的Windows NT操作系統(tǒng)也不同于OpenVMS和Tru64。因此,所述二進(jìn)制代碼轉(zhuǎn)換器系統(tǒng)調(diào)用對遺留操作系統(tǒng)來說必須是特定的。
直接匹配系統(tǒng)調(diào)用所述二進(jìn)制代碼轉(zhuǎn)換器能夠?qū)⒚總€(gè)系統(tǒng)調(diào)用映射為接近匹配的主處理器系統(tǒng)調(diào)用或者在或不在本機(jī)操作系統(tǒng)的幫助下對遺留系統(tǒng)調(diào)用的行為進(jìn)行仿真的代碼。例如,針對Intel IA-64微處理器體系結(jié)構(gòu)編寫的,用于將移除磁盤路徑(rmdir)Alpha Tru64 Unix系統(tǒng)調(diào)用轉(zhuǎn)換為等效的Intel IA-64 Linux系統(tǒng)調(diào)用的示范性匯編語言程序在下面示出<pre listing-type="program-listing"><![CDATA[/* *SYS_rmdir *Alpha 137<--->IA-64 l056 * *Inputsr32=char *pathname *Outputsint status */.proc xport_SYS_rmdirxport_SYS_rmdir MapPreamble r86,rTemp1,bSave1 // setup,save return address MakeIA64Addr param0,a0// setup first input mov r15=1056 // setup the syscall number break0x100000 // do syscall AdjustResults // fixup errno/indicator Return bSave1// done,return.endp]]></pre>這一承接程序的地址保存在一個(gè)表中,并且當(dāng)執(zhí)行Alpha 21264系統(tǒng)調(diào)用指令時(shí),處于Alpha寄存器$v0中的系統(tǒng)調(diào)用號用作進(jìn)入該表的索引。在該表位置處的所述地址用于轉(zhuǎn)移到這承接程序。這一承接程序僅將所需的參數(shù)(指向含有目錄名的字符串的指針)移送到Intel型IA-64處理器上的校正寄存器中,并將IA-64系統(tǒng)調(diào)用號(1056,而不是Alpha微處理器中的137)放到Intel IA-64微處理器中的寄存器15中。該系統(tǒng)調(diào)用返回一個(gè)指示值,代表成功的0或代表失敗的-1,該值被置于Alpha微處理器中的校正寄存器中。另一個(gè)值,“errno”(錯(cuò)誤號error number)表示失敗的原因。這個(gè)值在Alpha/Tru64系統(tǒng)和IA-64/Linux系統(tǒng)之間是互不相同的,因此必須要對這個(gè)值進(jìn)行轉(zhuǎn)換?!癆djustResult”宏指令借助另一個(gè)數(shù)據(jù)表來完成這一任務(wù)。一旦完成了轉(zhuǎn)換,errno值就被置于校正Alpha寄存器,并且承接程序準(zhǔn)備返回到常規(guī)的代碼執(zhí)行。IA-64中斷指令使用參數(shù)0x100000引發(fā)這一系統(tǒng)調(diào)用。
非直接匹配系統(tǒng)調(diào)用前面所述的例子說明了一種對現(xiàn)有的主處理器系統(tǒng)調(diào)用存在嚴(yán)格匹配的情況。不過,并不總是這樣的。例如,Alpha/Tru64 Unix“uname”系統(tǒng)調(diào)用是以多個(gè)文本流的形式返回關(guān)于機(jī)器的信息的。下面的例子就是這種系統(tǒng)調(diào)用的匯編語言承接程序的一個(gè)例子。
<pre listing-type="program-listing"><![CDATA[/* *SYS_uname *Alpha 207<--->IA-64 1130 * *Inputsr32=struct utsname *buf *Outputsint status */.proc xport_SYS_unamexport_SYS_uname MapPreamble r86,rTemp1,bSave1 // setup,save return address MakeIA64Addr param0,a0 // setup first input(sysname) br.call.sptk.few b0=callsysUname// do as a C function cmp·eq pTemp1,pTemp2=0,IA64Ret //was return value good?(pTemp1)mov v0=0//yes,fix up errno(pTemp1)mov a3=0// and error indicator(pTemp2)mov v0=14 //no,set errno to EFAULT(pTemp2)mov a3=-1 // and error indicator to -1 ReturnbSave1 //done,return.endp]]></pre>對這一系統(tǒng)調(diào)用直接進(jìn)行映射的問題是,遺留程序不是在處理器上運(yùn)行的,因?yàn)樽畛蹙褪沁@樣設(shè)計(jì)的。因此,這一承接程序調(diào)用一個(gè)C函數(shù)而不是直接使用Intel IA-64 Linux“uname”系統(tǒng)調(diào)用并對所得到的字符串進(jìn)行調(diào)整。
下面的例子表示用于對Linux“uname”系統(tǒng)調(diào)用的行為進(jìn)行重定義的C函數(shù)。注意這一函數(shù)是由上面的承接程序中的br.call.sptk.few指令調(diào)用的。
<pre listing-type="program-listing"><![CDATA[/* *This is a stub for the uname system call.Additional work must be *done for two reasons1)the size of the strings in the utsname *struct is different between IA-64/Linux and Alpha/OSF,and 2)we *really don’t want an Alpha/OSF program thinking it’s running on *IA-64/Linux. */INT64 callsysUname(char *uts_alpha){ struct utsname uts; //do the syscall,see if it works if(uname(&uts)<0) return-1; //this doesn’t work directly because the IA-64 utsname struct allows //for each string to be 64 bytes but the Alpha only allows for 32 //ALSO--FAKE IT OUT TO LOOK LIKE THE ALPHA! strcpy(&uts_alpha
,“OSF1”); strcpy(&uts_alpha[32],uts.nodename); strcpy(&uts_alpha[64],“VS.1”); strcpy(&uts_alpha[96],“732”); strcpy(&uts_alpha[128],“alpha”); return 0;}]]></pre>需要注意的是雖然使用了Linux“uname”系統(tǒng)調(diào)用,但是只有‘nodename,項(xiàng)傳送給了本機(jī)結(jié)果。虛擬了所有其它的信息組以使得該程序相信它自己是在Tru64 Unix操作系統(tǒng)上運(yùn)行,例如,版本5.1,build 732。
通過象這樣的技術(shù),能夠重新生成遺留操作系統(tǒng)的整個(gè)系統(tǒng)調(diào)用組。這一任務(wù)的復(fù)雜程度取決于遺留和本機(jī)操作系統(tǒng)之間的差異。對于Tru64操作系統(tǒng)上運(yùn)行的Alpha微處理器與Linux操作系統(tǒng)上運(yùn)行的Intel IA-64微處理器之間進(jìn)行轉(zhuǎn)換的情況,它們之間存在著許多的相似之處。
系統(tǒng)程序庫的替換如上面所討論的,可以將系統(tǒng)調(diào)用映射到主操作系統(tǒng)中。如上面所提到的,遺留應(yīng)用程序還與系統(tǒng)程序庫進(jìn)行聯(lián)系。取決于遺留應(yīng)用程序,使用本機(jī)處理器的系統(tǒng)程序庫而不是遺留程序庫是有可能的。這種方法的優(yōu)點(diǎn)在于本機(jī)程序庫有望更好地適于在本機(jī)系統(tǒng)上執(zhí)行。如果不能使用本機(jī)程序庫,那么就必須以一種或另一種形式使用遺留程序庫。
靜態(tài)與動(dòng)態(tài)鏈接使用系統(tǒng)程序庫的軟件應(yīng)用程序可以是靜態(tài)鏈接的,也可以是動(dòng)態(tài)鏈接的。對于靜態(tài)鏈接來說,從程序庫中得到的應(yīng)用程序所需要的代碼都送入到最終得到的應(yīng)用程序二進(jìn)制代碼載入模塊中。這生成了一個(gè)很好的但是比動(dòng)態(tài)鏈接要大的載入模塊,動(dòng)態(tài)鏈接是根據(jù)需要載入程序庫代碼的。對于動(dòng)態(tài)鏈接的應(yīng)用程序,在程序運(yùn)行的時(shí)候,必須要用到一個(gè)共享程序庫。
靜態(tài)鏈接應(yīng)用程序如果遺留應(yīng)用程序是靜態(tài)鏈接的,那么將有可能無法簡單地用本機(jī)程序庫代碼替換靜態(tài)鏈接的遺留程序庫代碼。因此,可以利用遺留應(yīng)用程序的間歇期對遺留程序庫代碼進(jìn)行轉(zhuǎn)換。按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器將不會知道遺留程序庫代碼的存在。不需要額外的遺留組件來產(chǎn)生完全轉(zhuǎn)換的本機(jī)二進(jìn)制代碼。
動(dòng)態(tài)鏈接應(yīng)用程序?qū)τ谑褂脛?dòng)態(tài)程序庫鏈接的應(yīng)用程序來說,載入模塊必須含有關(guān)于需要哪個(gè)程序庫的信息。而且還將給出有關(guān)哪些函數(shù)是未加解決的函數(shù)的信息。就這點(diǎn)來說,通常能夠使用本機(jī)程序庫替代遺留程序庫。這種替代是否能夠?qū)崿F(xiàn)取決于在本機(jī)系統(tǒng)上是否存在相同的功能性。如果這樣做了,就需要使用一個(gè)簡單的轉(zhuǎn)換承接程序來將參數(shù)轉(zhuǎn)移到校正寄存器中,這是由于遺留處理器和主處理器之間的函數(shù)調(diào)用協(xié)定很可能互不相同。下面的代碼實(shí)例表示一個(gè)Intel IA-64匯編語言承接程序的例子,該程序允許使用本機(jī)‘a(chǎn)tan’(arctangent反正切函數(shù))庫函數(shù)代替遺留庫函數(shù)。
<pre listing-type="program-listing"><![CDATA[//double atan(double x);.proc atanXportatanXport MapPreamblera,rTemp1,bSave1 // Save IA64 return addr in bSavel movfout0=fa0 // Move arg0 br.call.sptk.many b0=atan // Call ia64 routine movLegacyFpRet=IA64FpRet // Move IA64 return value to legacy Return bSave1 // Return.endp]]></pre>
如上所示,僅需要非常少的代碼就能夠?qū)ntel IA-64‘a(chǎn)tan’庫函數(shù)映射為Alpha版本,同時(shí)所得到的性能較之使用數(shù)量相對較大的代碼而言得到了提高。不過,這種方法要求能夠?qū)z留庫函數(shù)進(jìn)行識別并且要知道它需要那些參數(shù)。因此,它僅適用于常用庫函數(shù),而不能用于未知的遺留程序庫。
將遺留函數(shù)映射為本機(jī)函數(shù)的另一種方案是簡單地對遺留程序庫進(jìn)行代碼轉(zhuǎn)換。這顯然要求遺留程序庫可用于代碼轉(zhuǎn)換。這種處理方法得到與靜態(tài)鏈接應(yīng)用相同的結(jié)果,只是比使用本機(jī)程序庫要復(fù)雜一些,這是因?yàn)槿魏慰捎玫降倪z留程序庫都將要被使用,不管其所含有的函數(shù)是否已知。
存儲器配置附圖6是按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器中所使用的存儲區(qū)域的圖解表示。用附圖標(biāo)記54和56標(biāo)示的最前面的兩個(gè)存儲區(qū)域是第一個(gè)處理周期和第二個(gè)處理周期微碼區(qū)域,如上面所討論的。這些存儲區(qū)域含有經(jīng)轉(zhuǎn)換的本機(jī)指令,這些指令組成了經(jīng)轉(zhuǎn)換的遺留應(yīng)用程序。由附圖標(biāo)記58標(biāo)示的下一個(gè)區(qū)域是含有每個(gè)遺留指令處理器的微碼地址的向量空間。如上面所預(yù)先指明的,并不是該向量空間中的所有位置都含有有效的條目。該向量空間58所含有的條目的數(shù)量與遺留代碼指令的數(shù)量相同。最后那個(gè)區(qū)域是數(shù)據(jù)空間60。這些是所述遺留應(yīng)用程序載入模塊中所定義的數(shù)據(jù)部分。該數(shù)據(jù)空間60僅僅用于靜態(tài)數(shù)據(jù)或在載入模塊中進(jìn)行了明確定義的數(shù)據(jù)。遺留程序可以根據(jù)需要從堆陣中或自由存儲空間中指派存儲器。
根據(jù)需要,其它的存儲區(qū)域也可以提供給經(jīng)轉(zhuǎn)換的遺留應(yīng)用程序。這些存儲區(qū)域包括堆棧,該堆棧是從本機(jī)處理器存儲器組合中劃撥出來的并且從主處理器堆陣或自由存儲空間中動(dòng)態(tài)地請求存儲空間。
另一個(gè)可能存在的區(qū)域,它可以或不可以物理地位于所述主處理器存儲器中,是遺留代碼。除了上面所討論的動(dòng)態(tài)嘗試操作以外,一旦完成了代碼轉(zhuǎn)換,就不再需要這一信息。在這些情況下,可以從一個(gè)磁盤文件中將這一信息讀入到保存存儲器中。
寄存器配置按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器在性能方面一個(gè)主要的因素是其使用本機(jī)處理器寄存器的方法。下面將給出關(guān)于按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器如何使用本機(jī)處理器的寄存器進(jìn)行其遺留二進(jìn)制代碼的執(zhí)行的信息。對于不同的本機(jī)處理器來說這一信息可以是不同的。下面的信息是與Intel IA-64本機(jī)處理器和Alpha 21264遺留處理器相關(guān)的信息。
為了性能的緣故,將遺留處理器寄存器映射到本機(jī)處理器寄存器。許多現(xiàn)代微處理器體系結(jié)構(gòu)專門在寄存器中執(zhí)行幾乎所有的操作并且被迫從存儲器中載入值然后再沒必要地將結(jié)果保存回去,導(dǎo)致了相當(dāng)嚴(yán)重的性能惡化。
Alpha 21264處理器具有32個(gè)64位通用寄存器和32個(gè)64位浮點(diǎn)寄存器。Intel IA-64處理器具有128個(gè)64位通用寄存器和128個(gè)80位浮點(diǎn)寄存器。下面將給出Alpha/Tru64遺留系統(tǒng)和IA-64本機(jī)系統(tǒng)的寄存器配置。
將通用寄存器0-30中的值存儲在IA-64通用寄存器32-62中。
Alpha通用寄存器31總是讀為零并且能夠?qū)ζ鋵懭?,但是其值總是讀出零。IA-64通用寄存器0具有幾乎相同的特性,因此將Alpha寄存器31映射為Intel IA-64通用寄存器零。
將浮點(diǎn)寄存器0-30中的值存儲在IA-64浮點(diǎn)寄存器32-62中。
Alpha浮點(diǎn)寄存器31總是讀為零并且能夠?qū)ζ鋵懭耄瞧渲祵⒖偸亲x出零。IA-64浮點(diǎn)寄存器0具有幾乎相同的特性,因此將Alpha浮點(diǎn)寄存器31映射為Intel IA-64浮點(diǎn)寄存器0。
將16個(gè)IA-64通用寄存器指定為便箋式或臨時(shí)寄存器r63-r78。
將16個(gè)IA-64浮點(diǎn)寄存器指定為便箋式或臨時(shí)寄存器f63-f78。
將16個(gè)IA-64判定寄存器指定為便箋式或臨時(shí)寄存器p1-p16。判定寄存器用于存儲比較操作所得到的單位true/false結(jié)果。這些寄存器可以與幾乎所有的IA-64指令的執(zhí)行相對照著使用,以根據(jù)條件允許這些IA-64指令的執(zhí)行。Alpha 21264沒有等效寄存器。
將兩個(gè)IA-64轉(zhuǎn)移寄存器指定為便箋式或臨時(shí)寄存器b4-b5。轉(zhuǎn)移寄存器用于保存轉(zhuǎn)移指令的目的地地址。Alpha 21264使用通用寄存器來實(shí)現(xiàn)這一功能。
二進(jìn)制代碼轉(zhuǎn)換器系統(tǒng)的類圖附圖7和8表示二進(jìn)制代碼轉(zhuǎn)換器的UML類圖。其中包括了主要的功能組件,這些功能部件還帶有簡要說明。附圖7是按照二進(jìn)制代碼轉(zhuǎn)換器的功能單元的順序組織起來的并且重點(diǎn)強(qiáng)調(diào)了主系統(tǒng)。這里并沒有表示出所有的類。雖然并不能從這個(gè)圖表中明顯地看出,但是一組C++基本類組成了本二進(jìn)制代碼轉(zhuǎn)換器的基礎(chǔ)。該組類并不專門適合于任何具體的遺留處理器或主處理器。其中的另一層用于整合本機(jī)處理器的專有信息和遺留處理器的專有信息。
附圖8是以等級體系的方式組織的并且表示出了所有類自頂向下的體系結(jié)構(gòu)。其中并沒有示出本二進(jìn)制代碼轉(zhuǎn)換器的所有類。
代碼轉(zhuǎn)換過程示意圖附圖9表示代碼轉(zhuǎn)換過程示意圖。二進(jìn)制代碼轉(zhuǎn)換器會話管理程序?qū)ο?2位于代碼轉(zhuǎn)換過程的頂級。它依次對遺留處理程序子系統(tǒng)36和本機(jī)處理程序子系統(tǒng)40進(jìn)行調(diào)用。該圖中示出了六個(gè)總體步驟1.載入程序子系統(tǒng)34用于載入遺留程序。將遺留數(shù)據(jù)段無修改地提交給存儲器。遺留指令傳給該系統(tǒng)的用于代碼轉(zhuǎn)換的其余部分。
2.然后確定遺留指令的類型并且將這些遺留指令組合為以流程控制指令結(jié)束的遺留指令組。本步驟的輸出是一系列的LegacyProcedure對象,它們的每一個(gè)都含有LegacyInstruction對象的總量。這些對象的集合是遺留程序的指令部分。
3.如果存在轉(zhuǎn)換前優(yōu)化模塊64并且該模塊是有效的,則對其進(jìn)行調(diào)用。這些模塊對步驟2中生成的LegacyProcedure和LegacyInstruction對象進(jìn)行操作。
4.將LegacyInstruction轉(zhuǎn)換為本機(jī)處理器指令。本步驟的輸出是NativeInstruction對象,將這些對象添加到各個(gè)LegacyProcedure對象中。所有本機(jī)指令對象的集合是經(jīng)轉(zhuǎn)換程序的指令部分。
5.如果存在轉(zhuǎn)換后優(yōu)化模塊66并且該模塊是有效的,則對其進(jìn)行調(diào)用。這些模塊可能會利用LegacyProcedure和/或LegacyInstruction對象對步驟4中生成的NativeInstruction對象進(jìn)行操作。
6.最后一個(gè)步驟是將經(jīng)轉(zhuǎn)換的程序提交給本機(jī)處理器存儲器以準(zhǔn)備執(zhí)行或交付給一個(gè)由標(biāo)有“輸出程序”的塊68表示的磁盤文件以便今后使用。
指令轉(zhuǎn)換實(shí)例下面將給出用于將幾個(gè)具有代表性的Alpha 21264指令轉(zhuǎn)換為IA-64指令的代碼的實(shí)例。Alpha標(biāo)準(zhǔn)型使用這樣一種指令轉(zhuǎn)換結(jié)構(gòu)方式,該結(jié)構(gòu)方式為每個(gè)遺留Alpha指令提供一個(gè)稱為遺留指令轉(zhuǎn)換器的C函數(shù)并且為每個(gè)IA-64指令提供一個(gè)稱為本機(jī)指令發(fā)生器的C函數(shù)。之所以使用C函數(shù)是因?yàn)樗鼈兊牡刂纺軌虮4嬖谝粋€(gè)表中以便有效訪問。所述指令轉(zhuǎn)換器對遺留指令進(jìn)行檢查、提取操作代碼并彈出用于該條Alpha指令的遺留指令轉(zhuǎn)換器函數(shù)的地址。該遺留指令轉(zhuǎn)換器函數(shù)根據(jù)需要反過來使用本機(jī)指令發(fā)生器來產(chǎn)生IA-64指令。下面將對兩個(gè)Alpha指令的例子進(jìn)行探討。
ALPHA S4ADDQ,文字形式這條指令是一條用于將一個(gè)文字值加到一個(gè)已經(jīng)存在于寄存器中的值上的整型加法指令。下面給出的第一個(gè)例子表示用于這條Alpha指令的遺留指令轉(zhuǎn)換器。該函數(shù)調(diào)用兩個(gè)不同的IA-64指令發(fā)生器函數(shù)shladd和add_i14。這些C函數(shù)產(chǎn)生復(fù)制Alpha S4ADDQ指令的行為所需的IA-64二進(jìn)制指令。在調(diào)用了每個(gè)IA-64指令發(fā)生器函數(shù)之后,這些IA-64指令就被添加到轉(zhuǎn)換器子系統(tǒng)中以等候?qū)⑵涮峤唤o本機(jī)處理器存儲器和/或磁盤文件之前的進(jìn)一步處理。
遺留指令轉(zhuǎn)換器函數(shù)被Alpha到IA-64轉(zhuǎn)換器用于將Alpha 21264指令轉(zhuǎn)換為IA-64等價(jià)指令。在這種情況下,需要兩個(gè)IA-64指令。對于其它的遺留指令來說,將會需要更多或更少的指令。下面的第二個(gè)例子表示產(chǎn)生IA-64‘shladd’指令所需要的IA-64指令發(fā)生器函數(shù)。
<pre listing-type="program-listing"><![CDATA[/* *This function translates the Alpha instruction Scaled Add Quadword by 4. *S4ADDQ multiplies Ra by 4 and adds it to lit.The 64-bit sum is stored in Rc */INT64 S4ADDQ_LIT(Translator *translator,UINT64 Ra,UINT64 1it,UINT64 Rc){ NativeInstruction instr; //Get the necessary temp registers UINT64 rTemp1=translator->regMaps->getGPTempReg (); //Get the mapped IA64 registers for the input Alpha registers Ra=translator->regMaps->getMappedIA64GenReg (Ra); Rc=translator->regMaps->getMappedIA64GenReg (Rc); //Writes to the zero reg produce faults in IA64 but not in Alpha if(Rc!=GPRegZero) { //rTemp1=Ra * 4 shladd(translator,&instr,PredRegZero,rTemp1,Ra,2,GPRegZero); translator->addNativeInstruction(&instr); //Rc=rTemp1+1it adds_i14(translator,&instr,PredRegZero,Rc,1it,rTemp1); translator->addNativeInstruction(&instr); } return 0 ;}]]></pre>Alpha S4ADDQ文字形式指令轉(zhuǎn)換器函數(shù)<pre listing-type="program-listing"><![CDATA[//******************************************************************************//******************************************************************************// This function generates type A2 instructions.void genA2(Translator *translator,NativeInstruction *inst,UINT64 x4,UINT64 qp, UINT64 r1,UINT64 r2,UINT64 ct2,UINT64 r3){ inst->instr =(8UL<<37)|(x4<<29)|(ct2<<27)|qp|(r1<<6)| (r2<<13)|(r3<<20); inst->type=ALU; translator->regMaps->getGenRegMask(inst->srcRegsUsed,r2,r3); inst->srcRegType =General; translator->regMaps->getGenRegMask(inst->destRegUsed,r1); inst->destRegType =General; inst->predReg =translator->regMaps->getPredRegMask(qp);}void shladd(Translator *translator,NativeInstruction *inst,UINT64 qp,UINT64 r1, UINT64 r2,UINT64 count,UINT64 r3){ //IA64 needs count to be 1 less than actual number of bits to be shifted count--; genA2(translator,inst,4,qp,r1,r2,count,r3);}]]></pre>用于‘shladd’指令的IA-64指令發(fā)生器函數(shù)還需要注意的是寄存器重映射函數(shù)也是由遺留指令轉(zhuǎn)換器進(jìn)行處理的。另一個(gè)需要重點(diǎn)注意的問題是,在IA-64上執(zhí)行這個(gè)Alpha指令需要一個(gè)單臨時(shí)寄存器。
ALPHA CMOVEQAlpha CMOVEQ指令根據(jù)條件將一個(gè)值移送到一個(gè)Alpha通用寄存器中。用于這個(gè)指令的遺留指令轉(zhuǎn)換器可以在下面的例子中找到。這個(gè)Alpha指令再一次需要兩個(gè)IA-64指令,cmp.eq(8位直接形式)和add(寄存器形式)。
<pre listing-type="program-listing"><![CDATA[ /* *This function translates the Alpha instruction Conditional Move if Register *Equal to Zero,If register Ra is equal to 0,Rb is written to Rc. */INT64 CMOVEQ(Translator *translator,UINT64 Ra,UINT64 Rb,UINT64 Rc){ NativeInstruction instr; //Get the necessary temp registers UINT64 pTemp1=translator->regMaps->getPredTempReg (); UINT64 pTemp2=translator->regMaps->getPredTempReg (); //Get the mapped IA64 registers for the input Alpha registers Ra=translator->regMaps->getMappedIA64GenReg (Ra); Rb=translator->regMaps->getMappedIA64GenReg (Rb); Rc=translator->regMaps->getMappedIA64GenReg (Rc); //Writes to the zero reg produce faults in IA64 but not in Alpha if(Rc!=GPRegZero ) ( //Determine if Ra is equal to zero cmp_eq_i8(translator,&instr,PredRegZero,pTemp1,pTemp2,0,Ra); translator->addNativeInstruction(&instr); //conditionally do the move add_r(translator,&instr,pTemp1,Rc,GPRegZero,Rb); translator->addNativeInstruction(&instr); } return 0;}]]></pre>Alpha CMOVEQ遺留指令轉(zhuǎn)換器函數(shù)優(yōu)化程序?qū)嵗?IA-64代碼調(diào)度程序優(yōu)化程序下面的優(yōu)化程序?qū)嵗ㄟ^嘗試對經(jīng)轉(zhuǎn)換的指令進(jìn)行最佳調(diào)度利用IA-64 EPIC體系結(jié)構(gòu)來實(shí)現(xiàn)指令并行度的最大化。Itanium 2處理器每時(shí)鐘周期能夠執(zhí)行多達(dá)6條指令。必須將這些指令組成為具有3個(gè)41位指令以及一個(gè)5位template域的指令束,其中所述5位template域代表執(zhí)行這些指令需要那些處理器資源。該優(yōu)化程序?qū)Ρ緳C(jī)指令進(jìn)行分析,以根據(jù)數(shù)據(jù)相關(guān)性判定哪些指令可以安全地并行執(zhí)行,然后選擇指令束來匹配那些指令組。在附圖10中示出了這一總體過程。按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器將遺留程序分解為多個(gè)遺留指令組70。IA-64調(diào)度優(yōu)化程序然后將經(jīng)轉(zhuǎn)換的本機(jī)等價(jià)指令分解為IA-64指令組72、74、76。一個(gè)IA-64指令組中的所有指令能夠同時(shí)得以執(zhí)行,因此,在它們彼此之間不包含數(shù)據(jù)相關(guān)性。該優(yōu)化程序然后將IA-64指令組72、74、76分解為各自具有3條指令的IA-64指令束78、80、82、84、86和88。
這一調(diào)度算法僅應(yīng)用于Itanium 2和較新的IA-64處理器。不過,各種本機(jī)處理器都可以合理地受益于適用于它們的體系結(jié)構(gòu)的簡明指令調(diào)度算法。
IA-64體系結(jié)構(gòu)限定了有限數(shù)量的束類型。在同一個(gè)束中并不是所有的IA-64指令的組合都是合法的。例如,一種標(biāo)識為MMI的常用束類型,這代表在該束中含有兩個(gè)存儲器指令和一個(gè)整型指令。這些束的類型被編碼在這些束的5位template域中。謹(jǐn)慎選取束類型對避免處理器停頓來說是很重要的。最終,IA-64調(diào)度程序優(yōu)化程序使用一種謹(jǐn)慎設(shè)計(jì)的算法來為一個(gè)指令組中的IA-64指令選擇束類型。附圖11中示出了一種示范性的算法。
轉(zhuǎn)換過程實(shí)例下面的例子是一個(gè)針對Alpha遺留處理器和一個(gè)IA-64本機(jī)處理器的例子。將一組四個(gè)遺留Alpha指令轉(zhuǎn)換為IA-64指令并且為這個(gè)本機(jī)處理器對這些指令進(jìn)行適當(dāng)?shù)慕M織。
附圖12表示一小塊Alpha指令以及將它們轉(zhuǎn)換為IA-64指令的過程的圖解說明。這個(gè)附圖只表示了代碼轉(zhuǎn)換步驟,而并沒有優(yōu)化處理。遺留代碼塊總是以某種類型的流程控制指令結(jié)束,通常是跳轉(zhuǎn)指令或轉(zhuǎn)移指令,并且將這些遺留代碼塊稱為遺留進(jìn)程(雖然從初始源代碼的觀點(diǎn)來說它們可能并不真正代表一個(gè)完整的遺留進(jìn)程)。遺留進(jìn)程中的所有指令是順序地執(zhí)行的。這個(gè)例子假設(shè)已將遺留程序分解為各個(gè)遺留進(jìn)程并且單個(gè)進(jìn)程的代碼轉(zhuǎn)換正在進(jìn)行。
代碼轉(zhuǎn)換過程包括獲取單條遺留指令、根據(jù)操作碼(opcode)利用一個(gè)查找表格對其進(jìn)行解碼以及調(diào)用適當(dāng)?shù)倪z留指令代碼轉(zhuǎn)換器函數(shù),然后其按照需要構(gòu)造本機(jī)處理器指令。這一過程一般包括下述步驟1.可能需要一個(gè)或多個(gè)暫時(shí)(臨時(shí))寄存器。如果是這種情況,它們是從負(fù)責(zé)寄存器映射的X-port對象中申請的。對于IA-64本機(jī)處理器來說,是將IA-64的128個(gè)通用寄存器的一部分貢獻(xiàn)出來用作暫時(shí)寄存器的。
2.將遺留指令所使用的所有的遺留寄存器均映射為它們相應(yīng)的主處理器寄存器。再一次,還是由X-port的寄存器映射組件來進(jìn)行這一服務(wù)。
3.既然已經(jīng)對寄存器進(jìn)行了映射并且對暫時(shí)寄存器進(jìn)行了指定,那么如果需要,遺留代碼變換器函數(shù)調(diào)用本機(jī)指令發(fā)生器函數(shù)來以自然二進(jìn)制形式產(chǎn)生主處理器指令。就這個(gè)例子來說,需要七個(gè)不同的IA-64指令(sxt4使用了三次),并且,從而,使用了七個(gè)不同的本機(jī)指令發(fā)生器函數(shù)。
這一過程的輸出是一組連續(xù)時(shí)序本機(jī)處理器指令,它們最終執(zhí)行與遺留指令相同的功能。在附圖12中,對每個(gè)所得到的IA-64主處理器指令進(jìn)行了編號,以供進(jìn)一步引用。如圖中所看到的,對于所示的哪個(gè)Alpha指令,需要九個(gè)IA-64指令來進(jìn)行正確的仿真。這一數(shù)量可多可少,這取決于遺留指令的混合程度。
該組指令可就此打成一個(gè)程序包并照現(xiàn)在這樣執(zhí)行,不過這可能會導(dǎo)致IA-64主處理器的較差的性能。下述內(nèi)容簡要介紹了為了提高性能應(yīng)當(dāng)如何對這些指令進(jìn)行封包處理。雖然這一信息是IS-64專用的,但是其它的主處理器也能夠進(jìn)行并且需要類似的代碼重組來實(shí)現(xiàn)最高性能。
IA-64體系結(jié)構(gòu)需要將這些指令組合為指令束。指令束的編排方式見附圖13。每個(gè)束由三個(gè)IA-64指令組成,每個(gè)指令的長度是41位。每個(gè)束還含有一個(gè)5位template域,它用于說明這一組三個(gè)指令所需要的處理器資源。這些資源是處理器執(zhí)行單元。
附圖14表示一個(gè)Itanium 2處理器中能夠使用的執(zhí)行單元。這些執(zhí)行單元包括四個(gè)儲存器單元(它們還能夠執(zhí)行許多簡單的整型和邏輯指令)、兩個(gè)整型單元、兩個(gè)浮點(diǎn)單元(它們還能夠執(zhí)行長指令或擴(kuò)展指令)以及三個(gè)轉(zhuǎn)移單元。該附圖還示出了這些單元是如何由一組兩個(gè)指令束使用的。這將在下面做進(jìn)一步介紹。需要注意的是,如果有足夠的處理器資源可以使用,IA-64處理器每次能夠執(zhí)行兩個(gè)完整的指令束(六條指令)。
束中的template域指明了該束中的指令需要哪些執(zhí)行單元的組合。例如,template域值16代表代碼MIB,它意謂著需要使用一個(gè)存儲器單元、一個(gè)整型單元和一個(gè)轉(zhuǎn)移單元。Template域還可以規(guī)定一個(gè)stop條件,它意謂著所有當(dāng)前執(zhí)行的指令都必須在處理器接收到任何新的指令之前完成。Stop用于防止數(shù)據(jù)相關(guān)性的擾亂。Template 17也是一個(gè)MIB類型,只是在束的終端規(guī)定了一個(gè)stop。它由符號MIB表示。
術(shù)語IA-64指令組涉及全部都符合并行執(zhí)行的條件的一組IA-64指令。IA-64指令組最終都要組成為一個(gè)或多個(gè)末尾處必須含有一個(gè)stop的指令束。
使用關(guān)于IA-64主體系結(jié)構(gòu)的這一信息,可以對代碼轉(zhuǎn)換過程的下一步驟進(jìn)行檢驗(yàn)。附圖15表示用于IA-64主處理器的下一步驟。
附圖15表示從附圖12得到的彼此之間不含數(shù)據(jù)相關(guān)性的一組指令。這是一個(gè)單一的IA-64指令組。
IA-64主處理器具有良好性能的必要條件是,以不允許數(shù)據(jù)相關(guān)性擾亂的順序?qū)χ噶钸M(jìn)行適當(dāng)?shù)恼{(diào)度以最大化并行度。因此,IA-64的X-port的專用部分進(jìn)行對附圖12中所發(fā)出的指令流的分析,并且判斷哪些指令可以安全地同時(shí)執(zhí)行。在附圖15中,可以看到指令1、2、5、6和8彼此之間不具有寄存器相關(guān)性,并因此,它們能夠安全地并行執(zhí)行。不過,這是五條指令的一個(gè)序列。必須對IA-64指令束進(jìn)行選定以含有這些指令。然后將所得到的指令束提交給存儲器作為可執(zhí)行IA-64代碼的一部分。需要注意的是,IA-64 movl指令需要兩個(gè)束位置。
附圖16表示第二個(gè)IA-64指令組,它僅含有三條指令(3、7和9)。這個(gè)IA-64指令組適合于一個(gè)的MIB型單束。雖然在本例中沒有出現(xiàn),但是有可能出現(xiàn)沒有將指令束全部填滿的情況。在這些情況中,可以將不操作代碼插入到任意束位置中以使束完整。IA-64指令束的構(gòu)成代表這一過程的結(jié)束。一旦構(gòu)成了這種形式,IA-64指令就可由主處理器直接執(zhí)行了。
轉(zhuǎn)換后優(yōu)化實(shí)例下述內(nèi)容是一個(gè)可以在代碼轉(zhuǎn)換發(fā)生之后進(jìn)行調(diào)用的優(yōu)化程序的實(shí)例。該實(shí)例采用了一個(gè)Alpha遺留處理器和一個(gè)IA-64本機(jī)處理器。其目的是使用IA-64主處理器的稱為判斷的功能來消除短正向轉(zhuǎn)移。判斷允許根據(jù)條件指向一條或多條指令。
下面的例子表示一個(gè)簡單的C語言if-then結(jié)構(gòu),用于說明使用IA-64判斷功能的原因。(假設(shè)寄存器r5為a,r6為b,而r7為c。)如所看到的,如果a大于b,則變量c將會具有值0。否則,c將等于1。這種語句可以用圖中所示的匯編語言表示。
<pre listing-type="program-listing"><![CDATA[ if (a>b) { c=0; } else { c=1; }//PowerPC implementation--a conditional branch and an unconditional//branch are requiredcmpgtr5,r6 // compare′a′and′b′beq a_gt_b //jump if trueli r7,1 //c=1(false case)bdonea_gt_bli r7,0 //c=0(true case)done //continue executing here//IA-64 implementation--no branches required cmp.gt p1,p2=r5,r6 //compare′a′and′b′(p1) mov r7=o //if a>b,c=o(p2) mov r7=1 //else,c=1]]></pre>用匯編語言的等價(jià)語句簡化C語言的if-then語句絕大部分的現(xiàn)代微處理器體系結(jié)構(gòu)需要使用一個(gè)或多個(gè)轉(zhuǎn)移指令來根據(jù)條件為c賦值。然而IA-64執(zhí)行時(shí)不需要,其原因就是判斷功能。IA-64 cmp.gt指令對r5和r6進(jìn)行比較并將一個(gè)true或false(1或0)值保存到判定寄存器p1和p2中。這兩個(gè)寄存器中的結(jié)果被用于根據(jù)條件執(zhí)行下兩條指令。第一個(gè)mov只有當(dāng)p1=1時(shí)執(zhí)行。第二個(gè)mov只有當(dāng)p2=1時(shí)執(zhí)行。由于所給出的比較指令的比較的ture或flase結(jié)果返回到p1中并且將該結(jié)果的求反值返回到p2中,因此只有一條mov指令是有效的。而另一條指令將不會執(zhí)行。
這一概念可以用于消除短正向條件轉(zhuǎn)移。附圖17表示一小段含有一個(gè)短正向條件轉(zhuǎn)移指令(BEQ)的Alpha代碼。如果該轉(zhuǎn)移出現(xiàn)在地址100C,則1010和1014處的指令將不執(zhí)行。如果轉(zhuǎn)移條件沒有得到滿足,則該轉(zhuǎn)移失敗并且前面說的那兩條指令將會執(zhí)行。
如該圖所顯示的,BEQ指令可以由一個(gè)IA-64比較指令代替,該比較指令將其結(jié)果保存到IA-64判定寄存器中。然后可以利用這些判定寄存器根據(jù)條件執(zhí)行對應(yīng)于Alpha ORNOT和ADDQ指令的IA-64等價(jià)代碼,從而消除了一個(gè)不必要的條件轉(zhuǎn)移。這是非常有益處的,因?yàn)楝F(xiàn)代微處理器是沿著它們確信正確的指令路徑嘗試預(yù)取指令的。如果處理器錯(cuò)誤地判定了條件轉(zhuǎn)移發(fā)生與否,將會造成性能惡化,這是因?yàn)楸仨殞σ呀?jīng)存在于處理器的(多個(gè))管道中的誤判指令進(jìn)行刷新,并且必須沿著備用通路提取指令來執(zhí)行。出于這些原因,只要有可能,對條件轉(zhuǎn)移的消除通常是合乎需要的。
這個(gè)優(yōu)化程序?qū)嵗且粋€(gè)能夠利用本機(jī)處理器中有而遺留處理器中沒有的功能的例子。
該優(yōu)化模塊對經(jīng)代碼轉(zhuǎn)換的遺留代碼(所得到的IA-64代碼)進(jìn)行搜索來查找短正向條件轉(zhuǎn)移。當(dāng)其發(fā)現(xiàn)了這些條件轉(zhuǎn)移時(shí),它就消除這些轉(zhuǎn)移,產(chǎn)生用于比較的IA-64二進(jìn)制代碼,并修改將要進(jìn)行判定的指令。這一過程是在代碼轉(zhuǎn)換完成之后且在將本機(jī)指令提交給存儲器以備執(zhí)行之前發(fā)生的。因此,還是有可能改變它們的行為的。
轉(zhuǎn)換前優(yōu)化實(shí)例下面是轉(zhuǎn)換前優(yōu)化的一個(gè)例子。它允許內(nèi)嵌地執(zhí)行函數(shù)。內(nèi)嵌是一種編譯器技術(shù),它以“聯(lián)機(jī)”的方式展開函數(shù)的內(nèi)容,而不是設(shè)置為跳轉(zhuǎn)到函數(shù)本身。適于內(nèi)嵌的函數(shù)通常是短小并且不經(jīng)常調(diào)用其它函數(shù)的函數(shù)。函數(shù)內(nèi)嵌的缺點(diǎn)是無論在哪里調(diào)用函數(shù),都要對該函數(shù)的代碼進(jìn)行復(fù)制。這增加了程序?qū)Υ鎯ζ鞯男枨罅?。不過,現(xiàn)代本機(jī)處理器,例如IA-64,可能含有數(shù)十億字節(jié)的隨機(jī)存取存儲器。對于這種處理器來說,根本察覺不到函數(shù)內(nèi)嵌對存儲器造成的影響。
下面的例子表示一個(gè)小的C語言代碼實(shí)例。這里,funcX調(diào)用funcY,funcY執(zhí)行一個(gè)非常簡單的操作。優(yōu)化編譯器可以根據(jù)編程器所選定的最佳條件選擇決定內(nèi)嵌funcY。
<pre listing-type="program-listing"><![CDATA[ int funcX(int a) {funcY(a);//call funcY } int funcY(int b) { return b+7; } 調(diào)用一個(gè)小的C函數(shù)的C函數(shù)]]></pre>另一方面,按照本發(fā)明的二進(jìn)制代碼轉(zhuǎn)換器能夠在更廣泛范圍內(nèi)選擇用于為了速度而犧牲存儲器使用率的內(nèi)嵌的指令。對于每個(gè)內(nèi)嵌的函數(shù)來說,可以省略遺留代碼的下述部分1.初始化代碼通常為了執(zhí)行函數(shù)調(diào)用需要有一定數(shù)量的初始化。
該數(shù)量很可能是在多達(dá)六條遺留指令的范圍之內(nèi),不過在平臺與平臺之間可能是不同的。
2.無條件轉(zhuǎn)移一種‘跳轉(zhuǎn)’指令,將代碼執(zhí)行引導(dǎo)到所正在被調(diào)用的函數(shù)。
3.函數(shù)引導(dǎo)程序通常,函數(shù)包含某種類型的引導(dǎo)程序,通常由幾個(gè)指令組成。引導(dǎo)程序中所執(zhí)行的操作包括為數(shù)據(jù)區(qū)建立全局指針。
4.函數(shù)調(diào)用返回從函數(shù)返回通常包括一些清除指令。
5.無條件轉(zhuǎn)移一種‘返回’指令,將代碼執(zhí)行引導(dǎo)到進(jìn)行調(diào)用的函數(shù)。
在許多情況下,由于能夠消除大量的遺留代碼,內(nèi)嵌函數(shù)能夠?qū)崿F(xiàn)性能的提高。
這個(gè)優(yōu)化程序是在遺留代碼得以轉(zhuǎn)換之前但是在已經(jīng)對遺留代碼進(jìn)行組合之后對遺留代碼產(chǎn)生作用的。它搜索函數(shù)調(diào)用,并且當(dāng)其發(fā)現(xiàn)一個(gè)合法的內(nèi)嵌函數(shù)時(shí),就為該二進(jìn)制代碼轉(zhuǎn)換系統(tǒng)插入提示。
除了具有充足的存儲器使內(nèi)嵌比起最初的遺留系統(tǒng)來講更加可行之外,這種優(yōu)化方法并不是專門針對IA-64主處理器的性能而設(shè)計(jì)的。
顯然,根據(jù)上述的教導(dǎo),本發(fā)明的許多修改和改變都是可能實(shí)現(xiàn)的。因此,應(yīng)當(dāng)明白,在所附的權(quán)利要求書的范圍之內(nèi),除了上面所具體說明的方式之外,還可以以其它的方式實(shí)現(xiàn)本發(fā)明。
權(quán)利要求
1.一種二進(jìn)制代碼轉(zhuǎn)換器,包括一個(gè)載入程序子系統(tǒng),用于讀取遺留二進(jìn)制指令并將其載入到一個(gè)文件當(dāng)中;和一個(gè)代碼轉(zhuǎn)換器,用于直接將所述遺留二進(jìn)制指令轉(zhuǎn)換為本機(jī)二進(jìn)制指令,所述代碼轉(zhuǎn)換器對于使用不同的遺留處理器和本機(jī)處理器的應(yīng)用來說是可重新配置的。
全文摘要
本發(fā)明為一種終極管道和最優(yōu)重排技術(shù),涉及用于將針對遺留處理器編寫的二進(jìn)制指令直接轉(zhuǎn)換為本機(jī)處理器可執(zhí)行的二進(jìn)制指令的二進(jìn)制代碼轉(zhuǎn)換器。按照本發(fā)明的一個(gè)重要方面,將所述二進(jìn)制代碼轉(zhuǎn)換器配置成為一種可重新配置的代碼轉(zhuǎn)換器,這使得該二進(jìn)制代碼轉(zhuǎn)換器能夠用于不同的遺留處理器和/或操作系統(tǒng)和本機(jī)處理器。該二進(jìn)制代碼轉(zhuǎn)換器還進(jìn)行優(yōu)化,以利用更有效的本機(jī)處理器指令,并允許禁用部分遺留二進(jìn)制代碼和/或?qū)⑿碌谋緳C(jī)指令加入到應(yīng)用程序中而無需改變遺留二進(jìn)制代碼。
文檔編號G06F17/00GK1570870SQ20041000696
公開日2005年1月26日 申請日期2004年3月1日 優(yōu)先權(quán)日2003年3月13日
發(fā)明者E·W·茲沃納, G·P·克勞克, J·C·肯耐爾, T·R·郝瑞格, W·J·坎農(nóng) 申請人:諾斯羅普-格魯曼公司