lkcl | toshywoshy, openpowerbot's gone walkies! | 01:46 |
---|---|---|
programmerjake | after reading the messages I sent again, I realized I was ambiguous about what I though was best: I think having 1 mrsubcarry instruction is better than 2 or more instructions because it's waay simpler to implement in hardware...more RISC even though the instruction's pseudo-code is slightly more complex. | 02:00 |
programmerjake | luke, can you push the correct v0.2 tag to https://gitlab.com/nmigen/nmigen, without that it detects the version as 0.1 and other stuff will download 0.2 from pypi | 02:22 |
programmerjake | afaict the correct commit is 1025b98c279a5889e58bc27e7f183928dbbd1735 | 02:27 |
lkcl | programmerjake, the answer's still no, and going to remain at no. | 09:48 |
lkcl | i have repeated this about five or six times now. please listen | 09:48 |
lkcl | the answer is NO | 09:48 |
lkcl | six operands are TOO MANY | 09:48 |
lkcl | please listen when i say SIX OPERANDS IS TOO MANY | 09:48 |
lkcl | the answer is NO | 09:48 |
lkcl | why do you keep making me repeat things and why do you not listen? | 09:49 |
lkcl | you keep doing this, i don't understand it | 09:49 |
lkcl | no godddamn means NO | 09:49 |
lkcl | it's deeply distressing to me that you keep forcing me to repeat myself when i've clearly said NO | 09:50 |
programmerjake | which? git tag or something else? | 09:54 |
programmerjake | ah, mrsubcarry. | 09:54 |
ghostmansd | lkcl, a question on our favorite topic, msb0 | 10:01 |
ghostmansd | considering this record for svp64_prefix... | 10:02 |
ghostmansd | [SVP64_PREFIX_MAJOR] = {6, {0, 1, 2, 3, 4, 5}}, | 10:02 |
ghostmansd | that's as it follows in MSB0, right? | 10:02 |
ghostmansd | so, since the prefix is 32-bit in its whole glory... | 10:02 |
ghostmansd | ...this becomes {6, {31, 30, 29, 28, 27, 26}}, right? | 10:03 |
lkcl | yes | 10:25 |
lkcl | correct | 10:25 |
lkcl | there's some missing information: the number of bits | 10:26 |
lkcl | with a little thought i think you'll find that you need: {total field width, number of bits, {list of bits}} | 10:26 |
lkcl | for example, SVP64_PREFIX_MAJOR would be {32, 6, {31,30,29,28,27,26}} | 10:27 |
ghostmansd | We actually always know that in advance, don't we? | 10:34 |
ghostmansd | I mean, svp64_rm is 24 bits | 10:35 |
ghostmansd | And svp64_prefix is 32 bits | 10:35 |
ghostmansd | Why do we need to enumerate each and every field? | 10:35 |
ghostmansd | That is, regardless of which field we currently consider, it's part of the whole thing, and this thing has X bits | 10:36 |
ghostmansd | struct svp64_rm { uint32_t storage : 24; }; | 10:36 |
ghostmansd | struct svp64_prefix { uint32_t storage : 32; }; | 10:36 |
lkcl | ok if that's known-information, already, that's perfect | 10:37 |
ghostmansd | Also, I'm kinda unsure how gas outputs this stuff | 10:37 |
lkcl | the annoying bit is that the MSB0-to-LSB0 conversion process *has* to know the size | 10:37 |
lkcl | by someone having done 10,000 instructions *by hand*!!! | 10:38 |
ghostmansd | When we output the insn... what the result looks like eventually? | 10:38 |
lkcl | binary. bits. | 10:39 |
ghostmansd | Yeah, I understand... | 10:39 |
lkcl | actually, wrapped with ELF | 10:39 |
ghostmansd | I mean, the ordering | 10:39 |
lkcl | ah | 10:39 |
ghostmansd | I understand it ends up with bits... but how these bits are placed, that's the question. | 10:39 |
lkcl | that's completely separate, and ELF will specify the *byte* ordering as LE *byte* ordering or BE byte ordering | 10:40 |
ghostmansd | void | 10:40 |
ghostmansd | md_number_to_chars (char *buf, valueT val, int n) | 10:40 |
ghostmansd | { | 10:40 |
ghostmansd | if (target_big_endian) | 10:40 |
ghostmansd | number_to_chars_bigendian (buf, val, n); | 10:40 |
ghostmansd | else | 10:40 |
ghostmansd | number_to_chars_littleendian (buf, val, n); | 10:40 |
ghostmansd | } | 10:40 |
ghostmansd | I guess this is it | 10:40 |
lkcl | LSB0 is "exactly like how everyone else in computer science thinks numbers work" | 10:40 |
lkcl | yes. | 10:43 |
lkcl | don't for goodness sake confuse LSB0-MSB0 with LE-BE | 10:43 |
lkcl | LSB0-MSB0 is *bit* numbering | 10:43 |
lkcl | LE-BE is *byte* ordering | 10:43 |
ghostmansd | that I know | 10:44 |
ghostmansd | svp64_prefix.rm.eq(svp64_rm.spr) | 10:45 |
ghostmansd | yield ".long 0x%x" % svp64_prefix.insn.value | 10:46 |
ghostmansd | here.. we have bits set as MSB0, or as LSB0? | 10:46 |
ghostmansd | I mean, considering all the magic stuff that happens at SelectableInt and FieldSelectableInt | 10:47 |
ghostmansd | svp64_prefix = SVP64PrefixFields() | 10:47 |
ghostmansd | svp64_prefix.major.eq(SelectableInt(0x1, SV64P_MAJOR_SIZE)) | 10:47 |
ghostmansd | svp64_prefix.pid.eq(SelectableInt(0b11, SV64P_PID_SIZE)) | 10:47 |
ghostmansd | svp64_prefix.rm.eq(svp64_rm.spr) | 10:47 |
ghostmansd | Never mind, I'm going to check this practically :-) | 10:52 |
ghostmansd | https://pastebin.com/cUasiKgH | 11:00 |
ghostmansd | .long 0x540beef | 11:00 |
ghostmansd | Yeah I'm a cheater | 11:01 |
programmerjake | well, if you're llvm, you get away with thinking msb0 == BE and lsb0 == LE...I find that highly annoying: https://github.com/rust-lang/portable-simd/pull/267#issuecomment-1071046921 | 11:20 |
ghostmansd | holy crap | 11:32 |
lkcl | cheating is good! | 11:50 |
ghostmansd | actually, considering that we skipped all the gory details, `self.major = FieldSelectableInt(self.insn, tuple(range(0, 6)))' goes to `[SVP64_PREFIX_MAJOR] = {6, {5, 4, 3, 2, 1, 0}}' | 12:01 |
ghostmansd | that's, of course, is as long as your getter also considers the mapping | 12:02 |
ghostmansd | and, if we intend to use `prefix.storage' directly (`struct svp64_prefix { uint32_t storage; }')... | 12:04 |
ghostmansd | [SVP64_PREFIX_MAJOR] = {6, {26, 27, 28, 29, 30, 31}}, | 12:05 |
ghostmansd | lkcl, after thinking for a while, I think I want to follow your suggestion and generate this crap at sv_binutils.py | 12:35 |
ghostmansd | this works as charm: https://pastebin.com/fkxZa6q9 | 12:35 |
ghostmansd | I, however, don't want to hard-code this stuff, and instead will rely on SVP64PrefixFields and SVP64RMFields classes | 12:36 |
ghostmansd | they're not usable as is, need to do some updates so that I can get the desired functionality in a reliable way | 12:36 |
lkcl | ghostmansd, that's actually really useful for other purposes. (the table). i wonder if it could be merged with or somehow reproduce consts.py? | 13:16 |
lkcl | https://git.libre-soc.org/?p=openpower-isa.git;a=blob;f=src/openpower/consts.py;hb=HEAD | 13:16 |
ghostmansd | yes, but currently I'm thinking of subclassing SelectableInt so that the caller can specify the fields | 13:17 |
lkcl | ahh | 13:17 |
lkcl | nice | 13:17 |
ghostmansd | but yeah, we'll be able to work with this as a table :-) | 13:17 |
lkcl | why the hell didn't i think of that one | 13:17 |
ghostmansd | moreover, I think of custom __getattr__ which can do `self.spr' or `self.extra2' in a transparent fashion | 13:18 |
lkcl | or, passing in one of the members of const.py *to* a SelectableInt as its specification | 13:18 |
lkcl | there's a whole stack of possibilities here but for god's sake don't break anything | 13:19 |
lkcl | programmerjake, the mule is frickin awesome | 13:19 |
ghostmansd | lkcl, could you, please, recommend the best set of tests? I changed SVP64PrefixFields and SVP64RMFields classes, so I suspect there should be things to check | 16:10 |
ghostmansd | I haven't pushed it yet, because the changes are somewhat risky | 16:11 |
ghostmansd | I mean pushing to master; you might opt to check openpower-isa:binutils | 16:13 |
lkcl | ghostmansd, hm, let me find some | 16:27 |
lkcl | if you're really not comfortable push it into a branch, temporarily | 16:28 |
ghostmansd | yeah, that's what I did, as above :-) openpower-isa:binutils | 16:30 |
lkcl | all of these: https://git.libre-soc.org/?p=openpower-isa.git;a=tree;f=src/openpower/decoder/isa;hb=HEAD | 16:30 |
lkcl | test_caller_svp64*.py | 16:30 |
lkcl | they're reaaasonably short | 16:30 |
ghostmansd | aha OK | 16:30 |
ghostmansd | $(python src/openpower/decoder/isa), that's it? | 16:31 |
ghostmansd | ah no, there's no __main__ | 16:31 |
lkcl | well, i run them straight | 16:31 |
ghostmansd | ok :-) | 16:31 |
lkcl | nohup python3 openpower/decoder/isa/test_caller_svp64.py | 16:31 |
lkcl | but they shouuuuld also run under nosetests3 | 16:32 |
ghostmansd | https://pastebin.com/90BEd7nt | 16:34 |
ghostmansd | FIWIW this is how the entire things would look like | 16:34 |
ghostmansd | the real SelectableInt used as reference for all these FieldSelectableInt is `self' :-) | 16:35 |
lkcl | ha, cool | 16:35 |
lkcl | the next thing - the next cool thing - would be to create RecordObjects from those. | 16:36 |
lkcl | because right now they're all done by hand | 16:36 |
lkcl | but that's for another time | 16:36 |
ghostmansd | never saw RecordObject | 16:36 |
lkcl | it's one of the very early advanced classes i created on top of nmigen | 16:37 |
lkcl | where the hell is it :) | 16:38 |
lkcl | https://git.libre-soc.org/?p=nmutil.git;a=blob;f=src/nmutil/iocontrol.py;h=3d32a49bde120cca3b52f195c854f518afbc97ad;hb=HEAD#l94 | 16:39 |
ghostmansd | Whoa, I never realized we actually can set value of SelectableInt directly | 16:40 |
lkcl | where Record is forced to have a layout and is considered "nothing more than a contiguous sequence of bits some of which have different names" | 16:40 |
lkcl | yes, of course! | 16:40 |
ghostmansd | File "/home/ghostmansd/src/openpower-isa/src/openpower/decoder/isa/caller.py", line 993, in setup_next_insn | 16:40 |
ghostmansd | pfx.insn.value = opcode | 16:40 |
ghostmansd | I've always thought value is read-only :-) | 16:40 |
lkcl | yes, it's a hack - it's bypassing things. not really safe, but hey. | 16:40 |
lkcl | RecordObject you can do: | 16:41 |
ghostmansd | actually I can hack things on my side as well and simplify things as well... | 16:41 |
ghostmansd | but it's extremely ugly | 16:41 |
lkcl | class Obj(RecordObject): | 16:41 |
ghostmansd | like `self.spr = self' | 16:41 |
lkcl | self.x = Signal(5) | 16:41 |
lkcl | self.y = Signal(10) | 16:41 |
ghostmansd | Totally idiotic, but keeps backward compatibility | 16:41 |
ghostmansd | What do you think? | 16:41 |
lkcl | and a Record is *automatically* created Layout {x:5, y:10} | 16:41 |
ghostmansd | ah, nice! | 16:41 |
lkcl | oo what ugly hacks do you have in mind? | 16:42 |
ghostmansd | Well, I'd prefer explicit dict/tuple, not fields, but OK | 16:42 |
ghostmansd | https://pastebin.com/90BEd7nt | 16:42 |
lkcl | i love that | 16:42 |
ghostmansd | As you see, `spr' field is defined exactly like all fields... | 16:42 |
ghostmansd | not spr, insn | 16:42 |
ghostmansd | so, `insn' is defined like all fields... | 16:43 |
lkcl | ehmm.... it's a union in effect | 16:43 |
lkcl | amiright? | 16:43 |
ghostmansd | exactly, except that some bits might be non-contiguous | 16:43 |
lkcl | that'll cause absolute havoc for nmigen, but i do like it :) | 16:44 |
ghostmansd | all these fields you see as ranges/lists/whatever... | 16:44 |
ghostmansd | they're converted to FieldSelectableInt(self, len(field)) | 16:44 |
ghostmansd | but! | 16:45 |
lkcl | can you instead do it in the same way that SelectableInt/FieldSelectableInt does it? | 16:45 |
lkcl | so have | 16:45 |
lkcl | a) a SelectableIntmapping and a | 16:45 |
lkcl | b) FieldSelectableIntMapping | 16:45 |
ghostmansd | sorry, I don't quite get what you mean | 16:46 |
lkcl | where insn (as an example) would *bypass* the FieldSelectableInt and go *directly* to the SelectableInt? | 16:46 |
ghostmansd | ah, this | 16:46 |
lkcl | the problem is that nmigen does not have the concept of unions | 16:46 |
ghostmansd | there's no union | 16:46 |
lkcl | as a workaround to that, FieldSelectableInt has a *member* - its underlying SelectableInt | 16:46 |
ghostmansd | that's a dict of `FieldSelectableInt' which all map to `self' | 16:47 |
lkcl | https://git.libre-soc.org/?p=openpower-isa.git;a=blob;f=src/openpower/decoder/selectable_int.py;h=34ea01550174df96a7cd13896d0775e33575c7b8;hb=HEAD#l25 | 16:47 |
ghostmansd | when you instantiate SelectableIntMapping(0, 5, fields={"b": 1}) | 16:47 |
lkcl | 24 def __init__(self, si, br): | 16:47 |
lkcl | 25 self.si = si # target selectable int | 16:47 |
lkcl | 31 self.br = br # map of indices. | 16:48 |
ghostmansd | you create this: | 16:48 |
ghostmansd | self = SelectableInt(0, 5) | 16:48 |
lkcl | so what i am asking is: *don't* allow overlapping (don't allow insn) | 16:48 |
lkcl | but | 16:48 |
lkcl | provide a convention where it is *expected* that you can get at the *entire* range of bits | 16:48 |
ghostmansd | self.b = FieldSelectableInt(self, [1]) | 16:49 |
lkcl | and then self.b.si would be the way you would get at the *entire* range of bits | 16:49 |
lkcl | (aka "insn" in the example you gave) | 16:49 |
lkcl | am i making any sense? | 16:50 |
lkcl | i'd really love nmigen to have the concept of unions. i've seen it proposed before, so it's something that multiple people want | 16:51 |
lkcl | but... it's not available right now | 16:51 |
ghostmansd | I understand approximately :-) | 16:51 |
ghostmansd | but about convention... | 16:52 |
ghostmansd | what'd you say if https://pastebin.com/90BEd7nt | 16:52 |
lkcl | basically, provide a convention by which the *entirety* of the thing is accessible. full range. fully in sequence. | 16:52 |
ghostmansd | ...is replaced with https://pastebin.com/uP3CADbh | 16:52 |
ghostmansd | or, alternatively, is replaced with... | 16:53 |
lkcl | yeah, pffh, fine. | 16:53 |
lkcl | it'd probably be more like self.insn = self.underlying_object_wot_has_the_contiguous_range_set_by_bits_and_containing_value | 16:54 |
ghostmansd | ...replaced with https://pastebin.com/SW0zjvDC | 16:55 |
lkcl | yyeah that would work well | 16:55 |
ghostmansd | so, two options | 16:56 |
ghostmansd | https://pastebin.com/uP3CADbh is a hack, but makes SelectableIntMapping self-contained | 16:56 |
ghostmansd | https://pastebin.com/SW0zjvDC needs to instantiate a standalone SelectableInt, and makes SelectableIntMapping a thin wrapper around it | 16:56 |
lkcl | well if you do it like this: | 16:57 |
lkcl | class SelectableIntMapping: | 16:57 |
ghostmansd | (there's a third option: make FieldSelectableInt allow to set .value member, because that's currently what prevents us from working) | 16:57 |
lkcl | def __init__(self, *, value, bits=None, fields=None): | 16:57 |
lkcl | if isinstance(value, int): | 16:57 |
lkcl | value = SelectableInt(value, bits) | 16:57 |
lkcl | .... | 16:58 |
lkcl | then you have the best of both worlds | 16:58 |
lkcl | btw you know not to use a dictionary (or any mutable) as a default arg in a function, right? | 16:58 |
ghostmansd | OK, I'll think about it | 16:58 |
lkcl | that's a python pattern - a completely misunderstood and undocumented one - for a "singleton" | 16:58 |
lkcl | def singleton(fields={}): | 16:59 |
ghostmansd | you mean that it'll be populated by other calls | 16:59 |
lkcl | return fields | 16:59 |
lkcl | YES! | 16:59 |
ghostmansd | totally idiotic yeah | 16:59 |
ghostmansd | dict() instead of {} :-) | 16:59 |
lkcl | if you then modify the return result of that function, the next caller gets the | 16:59 |
ghostmansd | a real crap | 16:59 |
lkcl | no, you can't even do that! | 16:59 |
lkcl | you have to do: | 16:59 |
lkcl | def notasingleton(fields=None) | 16:59 |
lkcl | if fields is None: fields = {} # set the default to a dict | 17:00 |
lkcl | and continue from there | 17:00 |
lkcl | i can't count the number of times i've seen that mistake | 17:00 |
ghostmansd | ah yeah, indeed | 17:01 |
ghostmansd | I thought only {} are affected | 17:02 |
lkcl | being able to check the type of an argument and do something different is a really nice and powerful feature of python | 17:02 |
lkcl | sigh it's any mutable object | 17:02 |
lkcl | immutable objects such as frozenset() or tuple are perfectly fine | 17:02 |
ghostmansd | crap | 17:02 |
lkcl | so you can do | 17:02 |
lkcl | def notasingleton(fields=()): | 17:02 |
lkcl | .... | 17:02 |
lkcl | or | 17:02 |
ghostmansd | you know, sometimes I think that immutability by default is a good idea | 17:02 |
lkcl | def notasingleton(fields=frozenset()): | 17:02 |
lkcl | .... | 17:02 |
ghostmansd | and some languages do it | 17:03 |
lkcl | but not a list, dict, object(), or a class instance. | 17:03 |
lkcl | yyyeah you seen how much memory those use? :) | 17:03 |
lkcl | and how abysmally bad the hacks had to be for java users to pass around arrays of floats? | 17:04 |
lkcl | i know someone who "succeeded" at that by passing around arrays-of-integers instead, and performing type-casts back and forth. | 17:04 |
ghostmansd[m] | I think immutability, if it's enforced, should be followed by lazy copying | 17:06 |
ghostmansd | lkcl, updated SelectableIntMapping so that it has an additional parameter | 17:54 |
ghostmansd | I decided to leave the SI creation to the caller; if they want it to be optional, they can subclass | 17:55 |
ghostmansd | I also think this .eq is strange, and overall stuff should've been handled by properties/setattr (that is, `x.y = z' is better than `x.y.eq(z)'), but I don't want to enter this battle when I do something only because it looks nicer and then spent several hours fixing the code here and there | 18:01 |
ghostmansd | checked all test_caller_svp64*.py I found, things work, so I pushed it; please let me know if any issues appear | 18:05 |
ghostmansd | this whole stuff would have been _way_ more correct if SelectableInt was implemented as metaclass, not class | 18:27 |
ghostmansd | `SelectableInt of 32 bits' and `SelectableInt of 16 bits' are, logically, _distinct_ types, and they are distinguished by size in bits | 18:28 |
ghostmansd | Stuff like `SVP64RM_MMODE_SIZE = len(SVP64RMFields().mmode.br)' would have been dropped as well, leading to code like `SVP64RM_MMODE_SIZE = len(SVP64RMFields.mmode)' | 18:29 |
ghostmansd | OK, these were grumpy sessions with ghostmansd :-) | 18:30 |
ghostmansd | lkcl, I found that I still need this pseudo-field referring to the whole stuff for the code generation, but guess what? | 18:36 |
ghostmansd | it will work, combined with the previous idea | 18:37 |
ghostmansd | https://pastebin.com/8n9C4q34 | 18:40 |
ghostmansd | this code works since __getattr__ won't be called: the attribute can be resolved in a usual way | 18:41 |
lkcl | yes, good idea, si-creation caller convention. the checking of constructor parameter types was a way to allow both caller-creation and callee-creation | 19:39 |
lkcl | eq is used in nmigen because python assignment cannot be overridden | 19:39 |
lkcl | there is no "__assign__" in python by which you can override "x = y" ==> "x.__assign__(y)" | 19:40 |
lkcl | where with "x + y" you can override __add__ and it does "x.__add__(y)" | 19:41 |
lkcl | pyrtl *shudder* actually overrides the less-than-or-equal operator to perform assignment! | 19:41 |
lkcl | "p <= q" performs assignment! utterly awful, to break python syntax like that | 19:42 |
lkcl | but the reason why all of this is done at all is because nmigen *constructs an abstract syntax tree* | 19:42 |
lkcl | it does *not* actually perform an "actual add" or an "actual multiply" | 19:42 |
lkcl | it stores the fact that in the Hardware Design you want, ultimately, some *gates* to be laid down that perform an add | 19:43 |
lkcl | consequently you *really want* to override assignment (=) because you want to use this to say "at the Gate Level please set the NETLIST of the right-hand-side EQUAL to the LEFT side" | 19:44 |
lkcl | not | 19:44 |
lkcl | "make this python variable equal to this expression on the right" | 19:44 |
lkcl | with there being no __assign__ to override in python, the only choices left were to override another operator (the broken way that pyrtl does it) or simply use a function. | 19:45 |
lkcl | eq() was chosen. | 19:45 |
ghostmansd | Well, we actually can simulate assignments to individual fields via property decorator | 20:43 |
ghostmansd | And, in fact, this is one of the cases properties do well | 20:43 |
markos | lkcl, fyi, I will miss today's meeting but will join tomorrow | 21:28 |
programmerjake | we'll miss you... | 21:32 |
markos | been sleeping late, waking up early the past days and I don't think I can make it today :-/ | 21:33 |
programmerjake | hope you get more sleep :) | 21:35 |
markos | that's the idea, enjoy the meeting :) | 21:36 |
lkcl | jn sadoon_albader[m toshywoshy lxo klys meeting | 22:00 |
Generated by irclog2html.py 2.17.1 by Marius Gedminas - find it at https://mg.pov.lt/irclog2html/!