Tuesday, 2022-04-19

lkcltoshywoshy, openpowerbot's gone walkies!01:46
programmerjakeafter 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
programmerjakeluke, 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 pypi02:22
programmerjakeafaict the correct commit is 1025b98c279a5889e58bc27e7f183928dbbd173502:27
lkclprogrammerjake, the answer's still no, and going to remain at no.09:48
lkcli have repeated this about five or six times now. please listen09:48
lkclthe answer is NO09:48
lkclsix operands are TOO MANY09:48
lkclplease listen when i say SIX OPERANDS IS TOO MANY09:48
lkclthe answer is NO09:48
lkclwhy do you keep making me repeat things and why do you not listen?09:49
lkclyou keep doing this, i don't understand it09:49
lkclno godddamn means NO09:49
lkclit's deeply distressing to me that you keep forcing me to repeat myself when i've clearly said NO09:50
programmerjakewhich? git tag or something else?09:54
programmerjakeah, mrsubcarry.09:54
ghostmansdlkcl, a question on our favorite topic, msb010:01
ghostmansdconsidering this record for svp64_prefix...10:02
ghostmansd[SVP64_PREFIX_MAJOR] = {6, {0, 1, 2, 3, 4, 5}},10:02
ghostmansdthat's as it follows in MSB0, right?10:02
ghostmansdso, 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
lkclthere's some missing information: the number of bits10:26
lkclwith a little thought i think you'll find that you need: {total field width, number of bits, {list of bits}}10:26
lkclfor example, SVP64_PREFIX_MAJOR would be {32, 6, {31,30,29,28,27,26}}10:27
ghostmansdWe actually always know that in advance, don't we?10:34
ghostmansdI mean, svp64_rm is 24 bits10:35
ghostmansdAnd svp64_prefix is 32 bits10:35
ghostmansdWhy do we need to enumerate each and every field?10:35
ghostmansdThat is, regardless of which field we currently consider, it's part of the whole thing, and this thing has X bits10:36
ghostmansdstruct svp64_rm { uint32_t storage : 24; };10:36
ghostmansdstruct svp64_prefix { uint32_t storage : 32; };10:36
lkclok if that's known-information, already, that's perfect10:37
ghostmansdAlso, I'm kinda unsure how gas outputs this stuff10:37
lkclthe annoying bit is that the MSB0-to-LSB0 conversion process *has* to know the size10:37
lkclby someone having done 10,000 instructions *by hand*!!!10:38
ghostmansdWhen we output the insn... what the result looks like eventually?10:38
lkclbinary. bits.10:39
ghostmansdYeah, I understand...10:39
lkclactually, wrapped with ELF10:39
ghostmansdI mean, the ordering10:39
ghostmansdI understand it ends up with bits... but how these bits are placed, that's the question.10:39
lkclthat's completely separate, and ELF will specify the *byte* ordering as LE *byte* ordering or BE byte ordering10:40
ghostmansdmd_number_to_chars (char *buf, valueT val, int n)10:40
ghostmansd  if (target_big_endian)10:40
ghostmansd    number_to_chars_bigendian (buf, val, n);10:40
ghostmansd  else10:40
ghostmansd    number_to_chars_littleendian (buf, val, n);10:40
ghostmansdI guess this is it10:40
lkclLSB0 is "exactly like how everyone else in computer science thinks numbers work"10:40
lkcldon't for goodness sake confuse LSB0-MSB0 with LE-BE10:43
lkclLSB0-MSB0 is *bit* numbering10:43
lkclLE-BE is *byte* ordering10:43
ghostmansdthat I know10:44
ghostmansdyield ".long 0x%x" % svp64_prefix.insn.value10:46
ghostmansdhere.. we have bits set as MSB0, or as LSB0?10:46
ghostmansdI mean, considering all the magic stuff that happens at SelectableInt and FieldSelectableInt10: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
ghostmansdNever mind, I'm going to check this practically :-)10:52
ghostmansd.long 0x540beef11:00
ghostmansdYeah I'm a cheater11:01
programmerjakewell, 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-107104692111:20
ghostmansdholy crap11:32
lkclcheating is good!11:50
ghostmansdactually, 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
ghostmansdthat's, of course, is as long as your getter also considers the mapping12:02
ghostmansdand, 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
ghostmansdlkcl, after thinking for a while, I think I want to follow your suggestion and generate this crap at sv_binutils.py12:35
ghostmansdthis works as charm: https://pastebin.com/fkxZa6q912:35
ghostmansdI, however, don't want to hard-code this stuff, and instead will rely on SVP64PrefixFields and SVP64RMFields classes12:36
ghostmansdthey're not usable as is, need to do some updates so that I can get the desired functionality in a reliable way12:36
lkclghostmansd, 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
ghostmansdyes, but currently I'm thinking of subclassing SelectableInt so that the caller can specify the fields13:17
ghostmansdbut yeah, we'll be able to work with this as a table :-)13:17
lkclwhy the hell didn't i think of that one13:17
ghostmansdmoreover, I think of custom __getattr__ which can do `self.spr' or `self.extra2' in a transparent fashion13:18
lkclor, passing in one of the members of const.py *to* a SelectableInt as its specification13:18
lkclthere's a whole stack of possibilities here but for god's sake don't break anything13:19
lkclprogrammerjake, the mule is frickin awesome13:19
ghostmansdlkcl, could you, please, recommend the best set of tests? I changed SVP64PrefixFields and SVP64RMFields classes, so I suspect there should be things to check16:10
ghostmansdI haven't pushed it yet, because the changes are somewhat risky16:11
ghostmansdI mean pushing to master; you might opt to check openpower-isa:binutils16:13
lkclghostmansd, hm, let me find some16:27
lkclif you're really not comfortable push it into a branch, temporarily16:28
ghostmansdyeah, that's what I did, as above :-) openpower-isa:binutils16:30
lkclall of these: https://git.libre-soc.org/?p=openpower-isa.git;a=tree;f=src/openpower/decoder/isa;hb=HEAD16:30
lkclthey're reaaasonably short16:30
ghostmansdaha OK16:30
ghostmansd$(python src/openpower/decoder/isa), that's it?16:31
ghostmansdah no, there's no __main__16:31
lkclwell, i run them straight16:31
ghostmansdok :-)16:31
lkclnohup python3 openpower/decoder/isa/test_caller_svp64.py16:31
lkclbut they shouuuuld also run under nosetests316:32
ghostmansdFIWIW this is how the entire things would look like16:34
ghostmansdthe real SelectableInt used as reference for all these FieldSelectableInt is `self' :-)16:35
lkclha, cool16:35
lkclthe next thing - the next cool thing - would be to create RecordObjects from those.16:36
lkclbecause right now they're all done by hand16:36
lkclbut that's for another time16:36
ghostmansdnever saw RecordObject16:36
lkclit's one of the very early advanced classes i created on top of nmigen16:37
lkclwhere the hell is it :)16:38
ghostmansdWhoa, I never realized we actually can set value of SelectableInt directly16:40
lkclwhere 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
lkclyes, of course!16:40
ghostmansdFile "/home/ghostmansd/src/openpower-isa/src/openpower/decoder/isa/caller.py", line 993, in setup_next_insn16:40
ghostmansdpfx.insn.value = opcode16:40
ghostmansdI've always thought value is read-only :-)16:40
lkclyes, it's a hack - it's bypassing things. not really safe, but hey.16:40
lkclRecordObject you can do:16:41
ghostmansdactually I can hack things on my side as well and simplify things as well...16:41
ghostmansdbut it's extremely ugly16:41
lkclclass Obj(RecordObject):16:41
ghostmansdlike `self.spr = self'16:41
lkcl    self.x = Signal(5)16:41
lkcl    self.y = Signal(10)16:41
ghostmansdTotally idiotic, but keeps backward compatibility16:41
ghostmansdWhat do you think?16:41
lkcland a Record is *automatically* created Layout {x:5, y:10}16:41
ghostmansdah, nice!16:41
lkcloo what ugly hacks do you have in mind?16:42
ghostmansdWell, I'd prefer explicit dict/tuple, not fields, but OK16:42
lkcli love that16:42
ghostmansdAs you see, `spr' field is defined exactly like all fields...16:42
ghostmansdnot spr, insn16:42
ghostmansdso, `insn' is defined like all fields...16:43
lkclehmm.... it's a union in effect16:43
ghostmansdexactly, except that some bits might be non-contiguous16:43
lkclthat'll cause absolute havoc for nmigen, but i do like it :)16:44
ghostmansdall these fields you see as ranges/lists/whatever...16:44
ghostmansdthey're converted to FieldSelectableInt(self, len(field))16:44
lkclcan you instead do it in the same way that SelectableInt/FieldSelectableInt does it?16:45
lkclso have16:45
lkcla) a SelectableIntmapping and a16:45
lkclb) FieldSelectableIntMapping16:45
ghostmansdsorry, I don't quite get what you mean16:46
lkclwhere insn (as an example) would *bypass* the FieldSelectableInt and go *directly* to the SelectableInt?16:46
ghostmansdah, this16:46
lkclthe problem is that nmigen does not have the concept of unions16:46
ghostmansdthere's no union16:46
lkclas a workaround to that, FieldSelectableInt has a *member* - its underlying SelectableInt16:46
ghostmansdthat's a dict of `FieldSelectableInt' which all map to `self'16:47
ghostmansdwhen 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 int16:47
lkcl  31         self.br = br  # map of indices.16:48
ghostmansdyou create this:16:48
ghostmansdself = SelectableInt(0, 5)16:48
lkclso what i am asking is: *don't* allow overlapping (don't allow insn)16:48
lkclprovide a convention where it is *expected* that you can get at the *entire* range of bits16:48
ghostmansdself.b = FieldSelectableInt(self, [1])16:49
lkcland then self.b.si would be the way you would get at the *entire* range of bits16:49
lkcl(aka "insn" in the example you gave)16:49
lkclam i making any sense?16:50
lkcli'd really love nmigen to have the concept of unions.  i've seen it proposed before, so it's something that multiple people want16:51
lkclbut... it's not available right now16:51
ghostmansdI understand approximately :-)16:51
ghostmansdbut about convention...16:52
ghostmansdwhat'd you say if https://pastebin.com/90BEd7nt16:52
lkclbasically, 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/uP3CADbh16:52
ghostmansdor, alternatively, is replaced with...16:53
lkclyeah, pffh, fine.16:53
lkclit'd probably be more like self.insn = self.underlying_object_wot_has_the_contiguous_range_set_by_bits_and_containing_value16:54
ghostmansd...replaced with https://pastebin.com/SW0zjvDC16:55
lkclyyeah that would work well16:55
ghostmansdso, two options16:56
ghostmansdhttps://pastebin.com/uP3CADbh is a hack, but makes SelectableIntMapping self-contained16:56
ghostmansdhttps://pastebin.com/SW0zjvDC needs to instantiate a standalone SelectableInt, and makes SelectableIntMapping a thin wrapper around it16:56
lkclwell if you do it like this:16:57
lkclclass 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
lkclthen you have the best of both worlds16:58
lkclbtw you know not to use a dictionary (or any mutable) as a default arg in a function, right?16:58
ghostmansdOK, I'll think about it16:58
lkclthat's a python pattern - a completely misunderstood and undocumented one - for a "singleton"16:58
lkcldef singleton(fields={}):16:59
ghostmansdyou mean that it'll be populated by other calls16:59
lkcl    return fields16:59
ghostmansdtotally idiotic yeah16:59
ghostmansddict() instead of {} :-)16:59
lkclif you then modify the return result of that function, the next caller gets the16:59
ghostmansda real crap16:59
lkclno, you can't even do that!16:59
lkclyou have to do:16:59
lkcldef notasingleton(fields=None)16:59
lkcl    if fields is None: fields = {} # set the default to a dict17:00
lkcland continue from there17:00
lkcli can't count the number of times i've seen that mistake17:00
ghostmansdah yeah, indeed17:01
ghostmansdI thought only {} are affected17:02
lkclbeing able to check the type of an argument and do something different is a really nice and powerful feature of python17:02
lkclsigh it's any mutable object17:02
lkclimmutable objects such as frozenset() or tuple are perfectly fine17:02
lkclso you can do17:02
lkcldef notasingleton(fields=()):17:02
lkcl    ....17:02
ghostmansdyou know, sometimes I think that immutability by default is a good idea17:02
lkcldef notasingleton(fields=frozenset()):17:02
lkcl    ....17:02
ghostmansdand some languages do it17:03
lkclbut not a list, dict, object(), or a class instance.17:03
lkclyyyeah you seen how much memory those use? :)17:03
lkcland how abysmally bad the hacks had to be for java users to pass around arrays of floats?17:04
lkcli 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 copying17:06
ghostmansdlkcl, updated SelectableIntMapping so that it has an additional parameter17:54
ghostmansdI decided to leave the SI creation to the caller; if they want it to be optional, they can subclass17:55
ghostmansdI 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 there18:01
ghostmansdchecked all test_caller_svp64*.py I found, things work, so I pushed it; please let me know if any issues appear18:05
ghostmansdthis whole stuff would have been _way_ more correct if SelectableInt was implemented as metaclass, not class18:27
ghostmansd`SelectableInt of 32 bits' and `SelectableInt of 16 bits' are, logically, _distinct_ types, and they are distinguished by size in bits18:28
ghostmansdStuff 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
ghostmansdOK, these were grumpy sessions with ghostmansd :-)18:30
ghostmansdlkcl, I found that I still need this pseudo-field referring to the whole stuff for the code generation, but guess what?18:36
ghostmansdit will work, combined with the previous idea18:37
ghostmansdthis code works since __getattr__ won't be called: the attribute can be resolved in a usual way18:41
lkclyes, good idea, si-creation caller convention.  the checking of constructor parameter types was a way to allow both caller-creation and callee-creation19:39
lkcleq is used in nmigen because python assignment cannot be overridden19:39
lkclthere is no "__assign__" in python by which you can override "x = y" ==> "x.__assign__(y)"19:40
lkclwhere with "x + y" you can override __add__ and it does "x.__add__(y)"19:41
lkclpyrtl *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 that19:42
lkclbut the reason why all of this is done at all is because nmigen *constructs an abstract syntax tree*19:42
lkclit does *not* actually perform an "actual add" or an "actual multiply"19:42
lkclit stores the fact that in the Hardware Design you want, ultimately, some *gates* to be laid down that perform an add19:43
lkclconsequently 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"make this python variable equal to this expression on the right"19:44
lkclwith 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
lkcleq() was chosen.19:45
ghostmansdWell, we actually can simulate assignments to individual fields via property decorator20:43
ghostmansdAnd, in fact, this is one of the cases properties do well20:43
markoslkcl, fyi, I will miss today's meeting but will join tomorrow21:28
programmerjakewe'll miss you...21:32
markosbeen sleeping late, waking up early the past days and I don't think I can make it today :-/21:33
programmerjakehope you get more sleep :)21:35
markosthat's the idea, enjoy the meeting :)21:36
lkcljn sadoon_albader[m toshywoshy lxo klys meeting22:00

Generated by irclog2html.py 2.17.1 by Marius Gedminas - find it at https://mg.pov.lt/irclog2html/!