lkcl | cool. the code itself needs docstrings, and feel free to then cross-ref the howto/tutorial in the code as well. | 00:05 |
---|---|---|
lkcl | raise a bugreport for it, i'll add a budget | 00:05 |
lkcl | btw you made a homepage on http://libre-soc.org, right? | 00:05 |
lkcl | found it | 00:06 |
lkcl | https://libre-soc.org/klehman/ | 00:08 |
kylel | Will do | 00:49 |
ghostmansd | XLEN = 64 | 11:57 |
ghostmansd | REG = lambda v: SelectableInt(v, XLEN) | 11:57 |
ghostmansd | assert EXTS(REG(0xF0000A93), 32) == REG(0xFFFFFFFFF0000A93) | 11:57 |
ghostmansd | assert EXTS(REG(0x0000F074), 16) == REG(0xFFFFFFFFFFFFF074) | 11:57 |
ghostmansd | assert EXTS(REG(0x00000091), 8) == REG(0xFFFFFFFFFFFFFF91) | 11:57 |
ghostmansd | lkcl: please confirm the following are correct wrt XLEN and extsb/extsh/extsw | 11:57 |
ghostmansd | if yes, I suggest the following EXTS: | 11:57 |
ghostmansd | trunc_bits = min(value.bits, bits) | 11:57 |
ghostmansd | pad_bits = max(value.bits, bits) | 11:57 |
ghostmansd | return SelectableInt(exts(value.value, trunc_bits) & ((1 << pad_bits)-1), pad_bits) | 11:57 |
ghostmansd | def EXTS(value, bits=256): | 11:57 |
lkcl | values get first truncated to the 2nd argument | 12:58 |
lkcl | fllowed only then by analysis and sign-extension | 12:58 |
lkcl | assert EXTS(REG(0xF0000A93), 32) == REG(0xFFFFFFFFF0000A93) | 12:58 |
lkcl | assert EXTS(REG(0x70000A93), 32) == REG(0x000000070000A93) | 12:59 |
lkcl | EXTS you have to be extremely careful with it. | 13:00 |
lkcl | all values returned from EXTS **MUST** return a length of 256 | 13:01 |
lkcl | this is crticically, critically important | 13:01 |
lkcl | 256 indicates "this length is unlimited" | 13:01 |
lkcl | *ALL* of SelectableInt knows, "if the length is unlimited, you can safely set the length *to* the length of the inputs" | 13:02 |
lkcl | thus it is really not a good idea to change its behaviour | 13:03 |
lkcl | this is why there are totally separate EXT64 and EXT128 functions | 13:03 |
lkcl | so no, please don't alter EXTS - it will completely break pretty much everything. | 13:04 |
ghostmansd | lkcl: return SelectableInt(exts(value.value, bits) & ((1 << 256)-1), 256)? | 13:26 |
ghostmansd | the REG check is incorrect then, should be like this: | 13:26 |
lkcl | kylel, saw the bugreport, excellent - https://libre-soc.org/docs/testapi/ | 13:27 |
ghostmansd | assert EXTS(REG(0xF0000A93), 32) == SelectableInt(0xFFFFFFFFF0000A93, 256) | 13:27 |
lkcl | ah then yes | 13:27 |
ghostmansd | ack | 13:27 |
lkcl | wait... EXTS doesn't take an extra argument | 13:27 |
ghostmansd | now it takes: def EXTS(value, bits=256): | 13:27 |
lkcl | and shouldn't be made to | 13:27 |
ghostmansd | why not? | 13:28 |
lkcl | no, that's really important that it *not* be modified that way | 13:28 |
ghostmansd | we must introduce another function then | 13:28 |
lkcl | because it's implicit | 13:28 |
lkcl | EXTS has to conform to the Power ISA spec | 13:28 |
ghostmansd | in https://libre-soc.org/irclog/%23libre-soc.2021-09-29.log.html#t2021-09-29T09:41:37 | 13:28 |
ghostmansd | https://libre-soc.org/irclog/%23libre-soc.2021-09-29.log.html#t2021-09-29T09:40:25 | 13:28 |
lkcl | now, *behind the scenes* it can go, "oh, i am operating under conditions of XLEN=32. i should truncate things internally" | 13:29 |
lkcl | but even there we have to take EXTREME caution | 13:29 |
ghostmansd | so you mean we must, instead of `bits` argument, check self.XLEN? | 13:29 |
lkcl | because that could be a false assumption where a 128-bit partial result is handed to it | 13:29 |
ghostmansd | if so, this can be arranged | 13:29 |
lkcl | "what i suggest is just use EXTS((RA), 8)" | 13:30 |
lkcl | damn that was a mistake | 13:30 |
lkcl | i'm in the middle of administrative tasks for the budgeting at the moment | 13:31 |
lkcl | i'm not quite adapting from "calculator mode" onto this. | 13:31 |
lkcl | gimme a sec | 13:31 |
ghostmansd | well yes, that's why EXTS got a new argument :-) | 13:31 |
ghostmansd | no problem | 13:31 |
ghostmansd | I assume you want this | 13:31 |
ghostmansd | return SelectableInt(exts(value.value, self.XLEN) & ((1 << self.XLEN)-1), 256) | 13:31 |
ghostmansd | oh no, wait | 13:32 |
ghostmansd | return SelectableInt(exts(value.value, self.XLEN) & ((1 << 256)-1), 256) | 13:32 |
ghostmansd | this | 13:32 |
lkcl | that was my initial thought, but even that is "damaging" | 13:32 |
lkcl | because the assumption of EXTS as it stands is that it can be passed *anything*, of *any* length | 13:32 |
lkcl | even an intermediate results from e.g. a 64-bit multiply producing a 128-bit result | 13:33 |
lkcl | an assumption that it **MUST** truncate to XLEN would go: | 13:33 |
lkcl | "oh, you had a 128-bit result? well, tough titty, i truncate everything to XLEN-bit before sign-extending, and XLEN=64 so i'm throwing away the top 64 bits" | 13:34 |
lkcl | more to the point: i don't think EXTS even *needs* modifying | 13:34 |
lkcl | all inputs should have been already truncated to XLEN | 13:34 |
ghostmansd | XLCASTU? | 13:35 |
lkcl | all outputs *will* be post-analysed and truncated / sign-extended / saturated as a *separate* phase | 13:35 |
lkcl | that's differerent | 13:35 |
lkcl | what XLCASTU does is a completely different matter | 13:35 |
ghostmansd | it truncates/zero-extends to XLCASTU | 13:36 |
lkcl | but should *not* be implemented internally using EXTS (forcing EXTS to be modified) | 13:36 |
lkcl | great. | 13:36 |
lkcl | that's explicit | 13:36 |
lkcl | because it *has* to be XLEN-aware | 13:36 |
ghostmansd | lkcl, I must confess you make things more confusing :-) | 13:36 |
ghostmansd | let's wait for a moment till you have time | 13:36 |
lkcl | EXTS very very much does not. it is defined - *defined* - as "taking its input, respecting its input's length, and performing sign-extension from that" | 13:37 |
lkcl | examples. i need examples. | 13:37 |
lkcl | i can't think about this in the abstract without concrete examples | 13:37 |
lkcl | which really need to be done on a bugreport, not IRC | 13:37 |
lkcl | EXTS is one of those weird annoying functions where we had to conform to a nebulous *implicit* aspect of the Power ISA pseudocode / specification | 13:38 |
ghostmansd | EXTS(XLCASTU(SelectableInt(0xF0000A93, 64))) == SelectableInt(value=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000a93, bits=256) | 13:39 |
lkcl | blech! | 13:39 |
ghostmansd | this ^ is for XLEN=32 | 13:40 |
lkcl | that looks right | 13:40 |
ghostmansd | on XLEN=64... | 13:40 |
ghostmansd | EXTS(XLCASTU(SelectableInt(0xF0000A93, 64))) == SelectableInt(value=0xf0000a93, bits=256) | 13:41 |
ghostmansd | still OK? | 13:41 |
lkcl | should be 0xf00000a93... yes | 13:41 |
ghostmansd | note that with these, pesudocode looks like... | 13:41 |
lkcl | XLCASTU should be where the explicit handling of XLEN is involved | 13:42 |
ghostmansd | extsb: RA <- EXTS(XTRUNC(RS)), XLEN=8 | 13:42 |
ghostmansd | extsb: RA <- EXTS(XTRUNC(RS)), XLEN=16 | 13:42 |
ghostmansd | *extsh | 13:42 |
ghostmansd | extsw: RA <- EXTS(XTRUNC(RS)), XLEN=32 | 13:42 |
lkcl | tck...tck...tck... | 13:42 |
* lkcl thinks | 13:42 | |
lkcl | ermm.... ermermerm... | 13:42 |
ghostmansd | so there won't be explicit 8/16/32 | 13:42 |
ghostmansd | but, instead, when we get to extsb, we already get there with XLEN=8 | 13:43 |
lkcl | that clearly can't be the case | 13:43 |
ghostmansd | and this affects XTRUNC | 13:43 |
lkcl | extsb clearly can't be exactly the same as extsw and extsh | 13:43 |
lkcl | it would have to be something like | 13:43 |
lkcl | extsb: RA <- EXTS(XTRUNC(RS, 8)) | 13:43 |
lkcl | extsh: RA <- EXTS(XTRUNC(RS, 16)) | 13:44 |
ghostmansd | XTRUNC doesn't have explicit argument | 13:44 |
ghostmansd | return SelectableInt(value.value, self.XLEN) | 13:44 |
ghostmansd | heck | 13:44 |
ghostmansd | XLCASTU | 13:44 |
ghostmansd | that you previously called XTRUNC | 13:44 |
lkcl | ah ok | 13:44 |
lkcl | ermmm... ermermerm... | 13:44 |
ghostmansd | also we have XLCASTS | 13:45 |
ghostmansd | return SelectableInt(exts(value.value, self.XLEN), self.XLEN) | 13:45 |
ghostmansd | also w/o explicit arguments | 13:45 |
lkcl | ok then it should be changed to have an explicit argument | 13:45 |
lkcl | specifying the length | 13:45 |
lkcl | where that length is then truncated to max(length, self.XLEN) | 13:46 |
ghostmansd | I suspect that we have a separate function then | 13:47 |
ghostmansd | XL is implicitly XLEN | 13:47 |
ghostmansd | XLCASTU -- cast to XLEN unsigned | 13:47 |
ghostmansd | so it'll be the initial version of EXTS I posted, but named differently, that's what I suggest. | 13:48 |
lkcl | tck, tck, tck.... | 13:48 |
* lkcl thinks | 13:48 | |
lkcl | this needs a table written out | 13:50 |
ghostmansd | def EXTS_with_moo_powers(value, bits): | 13:50 |
ghostmansd | bits = max(bits, self.XLEN) | 13:50 |
ghostmansd | return SelectableInt(exts(value.value, bits) & ((1 << 256)-1), 256) | 13:50 |
lkcl | can you write out a full table in the bugreport | 13:50 |
lkcl | with extsb, extsh and extsw on the columns | 13:50 |
lkcl | XLEN=8/16/32/64 as the rows | 13:50 |
ghostmansd | extsb: RA <- EXTS_moo(RB, 8) | 13:50 |
ghostmansd | extsh: RA <- EXTS_moo(RB, 16) | 13:51 |
ghostmansd | extsw: RA <- EXTS_moo(RB, 32) | 13:51 |
lkcl | and some example values as | 13:51 |
lkcl | ghostmansd: this is too complex to do over IRC | 13:51 |
lkcl | it needs a wiki page | 13:51 |
lkcl | with some examples - a full table | 13:51 |
ghostmansd | > can you write out a full table in the bugreport | 13:51 |
ghostmansd | OK will post to bugzilla | 13:51 |
ghostmansd | I don't quite get what's complex here, but OK :-) | 13:52 |
lkcl | i can't cope with it without seeing everything at once, that's what | 13:52 |
ghostmansd | ack | 13:52 |
lkcl | unless i can see *all* the potential combinations, i can't work out what needs to be done | 13:52 |
lkcl | it needs a wiki page | 13:52 |
lkcl | rather than going in the bugreport | 13:52 |
ghostmansd | ok | 13:52 |
lkcl | 1 sec | 13:53 |
ghostmansd | i'll create one | 13:53 |
lkcl | docs/something | 13:53 |
lkcl | http://libre-soc.org/docs/xlen_handling or something | 13:53 |
lkcl | or better, under the svp64 page | 13:53 |
lkcl | https://libre-soc.org/openpower/sv/svp64/xlen_handling | 13:54 |
lkcl | something like that | 13:54 |
ghostmansd | https://libre-soc.org/openpower/sv/svp64/extsxl/ | 15:07 |
ghostmansd | lkcl: I did it quickly, feel free to expand | 15:07 |
lkcl | ghostmansd[m], i mean as a 2D table, not a 1D list | 15:38 |
lkcl | a 1D list the patterns are not clear | 15:38 |
lkcl | because the eye has to jump text and cannot spot vertical and horizontal patterns at the same time | 15:38 |
lkcl | until i've seen those examples laid out with the values (some signed, some unsigned), i'm literally unable to see the patterns which allow me to deduce how this needs to work | 15:40 |
lkcl | here's how i did it for dynamic simd __eq__: | 15:41 |
lkcl | https://libre-soc.org/3d_gpu/architecture/dynamic_simd/eq/ | 15:41 |
lkcl | i was then able to write out some Karnaugh maps (32 of the damn things) | 15:42 |
lkcl | on paper (!) | 15:42 |
lkcl | and was able to mathematically reduce them down to an algorithm | 15:42 |
ghostmansd[m] | What fields do you want? XLEN, sign, instruction? | 16:59 |
lkcl | i added 3 copies of a 2D table which has XLEN=64/32/16/8 across the columns and extsb/h/w across the rows | 17:47 |
lkcl | that leaves placing several signed and unsigned values in the TODO value 1 TODO value 2 TODO value 3 | 17:47 |
lkcl | where for completeness - to see precisely what is going on - we need a full suite of unsigned values as well | 17:51 |
lkcl | these actually could end up as the unit test values | 17:51 |
lkcl | i removed the pseudocode from the examples because it is misleading as to what is needed | 17:51 |
lkcl | the tables should contain the *desired* values | 17:52 |
lkcl | not the values that "happen to be calculated by an algorithm which may or may not produce the right answer(s), we don't know yet" | 17:52 |
ghostmansd[m] | lkcl, ack | 18:02 |
Generated by irclog2html.py 2.17.1 by Marius Gedminas - find it at https://mg.pov.lt/irclog2html/!