From: Luke Kenneth Casson Leighton Date: Tue, 18 Apr 2023 15:30:22 +0000 (+0100) Subject: add extsb/h/w example of XLEN X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=315cfdb906e073ef61ca71a00713163b895c6cb8;p=libreriscv.git add extsb/h/w example of XLEN see https://bugs.libre-soc.org/show_bug.cgi?id=1061 and https://bugs.libre-soc.org/show_bug.cgi?id=988 --- diff --git a/openpower/sv/rfc/ls005.mdwn b/openpower/sv/rfc/ls005.mdwn index b2981600c..6dd666ad9 100644 --- a/openpower/sv/rfc/ls005.mdwn +++ b/openpower/sv/rfc/ls005.mdwn @@ -164,6 +164,10 @@ do i = 0 to ((XLEN/8)-1) RA[(i*8):(i*8)+7] <- n ``` +Here as the instruction's intent is to count bytes, and RA contains on +a per-byte basis a SIMD-style count of each byte's 1s, it becomes possible +to simply count less bytes. + ## no modification needed, but function changes For the `addi` instruction there is no apparent change: @@ -229,6 +233,72 @@ When XLEN=8 "half register width" is clearly 4 bit, thus the LSB nibble is teste but still sign-extended for comparison against the 16-bit signed immediate. +## Extend Sign byte/half/word + +This instruction can be redefined again in terms of: + +* "Word" meaning "Half of register width" +* "Half-word" meaning "Quarter of register width" +* "Byte" meaning "One-eighth of register width" + +And a table results as follows: + +``` + XLEN=8: + extsb: 1-bit -> 8-bit sign extension + extsh: 2-bit -> 8-bit sign extension + extsw: 4-bit -> 8-bit sign extension + XLEN=16: + extsb: 2-bit -> 16-bit sign extension + extsh: 4-bit -> 16-bit sign extension + extsw: 8-bit -> 16-bit sign extension + XLEN=32: + extsb: 4-bit -> 32-bit sign extension + extsh: 8-bit -> 32-bit sign extension + extsw: 16-bit -> 32-bit sign extension + XLEN=64: + extsb: 8-bit -> 64-bit sign extension + extsh: 16-bit -> 64-bit sign extension + extsw: 32-bit -> 64-bit sign extension +``` + +If the instructions were kept as presently defined then there +is a loss of functionality and opportunity: + +``` + XLEN=8: # completely wasted opportunity + extsb: 8-bit -> 8-bit does nothing + extsh: 16-bit -> 8-bit truncates + extsw: 32-bit -> 8-bit truncates + XLEN=16: # wasted 2/3 of encoding + extsb: 8-bit -> 16-bit sign extension + extsh: 16-bit -> 16-bit does nothing + extsw: 32-bit -> 16-bit truncates + XLEN=32: # wasted 1/3 of encoding + extsb: 8-bit -> 32-bit sign extension + extsh: 16-bit -> 32-bit sign extension + extsw: 32-bit -> 32-bit does nothing + XLEN=64: # unchanged (default) behaviour + extsb: 8-bit -> 64-bit sign extension + extsh: 16-bit -> 64-bit sign extension + extsw: 32-bit -> 64-bit sign extension +``` + +The RTL for `extsb` becomes: + +``` + in <- (RA)[XLEN-8:XLEN-1] + if XLEN = 8 then RT <- in[0]] * 8 # 1->8 + if XLEN = 16 then RT <- in[13]] * 15 || in[15] # 2->16 + if XLEN = 32 then RT <- in[28]] * 29 || in[29:31] # 4->32 + if XLEN = 64 then RT <- in[55]] * 56 || in[57:63] # 8->64 +``` + +And `extsh` and `extsw` follow similar logic. Interestingly there is +no loss of functionality compared to keeping `extsb` always as "byte +sign-extending" and ironically the loss of opportunity *is* to keep +`extsb` the same regardless of XLEN. + \newpage{} [[!tag opf_rfc]]