Live data from Hacker News

RISC-V Assembler: Arithmetic

projectf.io

31–40 of 48 posts

Re: RISC-V Assembler: Arithmetic

#31
post #13

Earlier quoted context omitted.

> and the x86 assembly syntax where the destination is the last register. ITYM AT&T :). The idea is that the basic grammar is common across architectures to help compiler backend authors. The historical reason for the ordering is because that’s how it was on the PDP-11, the “mother” assembly. And all AT&T/GNU versions preserve this ordering regardless of the vendor format. > The other is the syntax most commonly used…

> The historical reason for the ordering is because that’s how it was on the PDP-11 True, I think. I mean, that certainly was the case for PDP-11 and VAX asm. 68000 too (pretty much a 32 bit, 16 register PDP-11). Whether that was the actual reason is more debatable. > And all AT&T/GNU versions preserve this ordering regardless of the vendor format. False. GNU `as` puts the destination register first for all of Arm32,…

Yes absolutely right about the modern RISC archs. I should have just said AT&T not AT&T/GNU. The difference is that x86, VAX and SPARC were AT&T UNIX porting efforts prior to or alongside GNU, and GNU sort of chose to inherit that. The newer RISC architectures did not have the hand/influence of AT&T as far as I know.

As far as the operand ordering with the x86, the thing is they did flip it from the Intel syntax and the beginnings of this port date back to Version 7 (1978), a few years before GNU. So what was the reason other than it looked like the incumbent/precedent PDP-11? I haven't heard it being much more than circumstance.

Re: RISC-V Assembler: Arithmetic

#32
post #21

Earlier quoted context omitted.

> fringe ISAs Itanium fringe? You’re clueless and have no credibility. We’re talking about an = instead of a , … you’re needlessly bringing up “crazy ASTs”, so much for being argumentative. And defensive? You seem mixed up, I’m not the one even advocating for the damn things. But your argument is ignorant and foolish. > Assembly is meant to map directly to the way the machine code is written This is just false. https…

> Itanium fringe? You’re clueless Very fringe. A huge market failure. Hardware discontinued. Support removed in LLVM (2.6), and the Linux kernel (6.7). Still seems to be hanging on in GCC, though it was initially going to be deprecated in GCC 10. One of the very few ISAs I've never actually seen a real machine of, let alone used. And I've worked professionally on i960 (Stratus fault-tolerant computer), which not many…

That it was a failure is well known. But fringe, as in obscure (which is what I think is salient in this context)? I think that is misleading - that it has an official gcc backend to remove is a sufficient counterargument. Funny you mentioned PA-RISC and Alpha, as both were abandoned by HP and Compaq for it. Stupid (at least HP did backpedal, but not after burning a mountain of cash, it was to replace the PA), but not consistent with fringe. Getting it into the Linux kernel and gcc support was a big deal at the time thousands of man-hours were expended on all of this, all the investment and work was done for the dominant architecture. Obviously Microsoft was hugely invested in it, but some there thankfully had better ideas and didn’t miss the x86-64 boat, since it already stank years prior to its release. DEC Alpha was also in the long run a commercial failure. wouldn't call it fringe though. PA-RISC was commercially middling, I also wouldn't call it fringe (both shitcanned for Itanic BTW, for which people are still bitter).

Re: RISC-V Assembler: Arithmetic

#33
post #29
post #26

Earlier quoted context omitted.

Because from the CPU perspective, «+» is ambiguous as there is not one «addition» but many: - signed add - unsigned add - add and carry There are a few others in other ISA', then there are the operand sizes (byte, half-word, word, long word etc) and the «+» operator does not capture the operand size nor the specifics whereas - rd = rs1 addu8 rs2 makes the intention clear: «add the lower 8 bits from rs2 to rs1, don't…

Good post! ok, for rd = rs1 addu8 rs2 use rd = rs1 +u8 rs2 etc. The + stands out, more clearly indicating addition. (to me anyway) As for commutativity of +, it's not necessarily true. It depends entirely on what underlying operation + denotes. It's perfectly reasonable to use it for string concatenation, and that clearly isn't commutative. But if it's not in the case of an ISA, that's fine, just have the assembler r…

Obviously that doesn't generalize for opcodes with 0, 1, 3 or more input operands. As a concrete example, consider a fused multiply-add operation: `rd = fma rs1, rs2, rs3` is consistent, but how would you convert it to an infix notation?

Re: RISC-V Assembler: Arithmetic

#34
post #8

> ProTip: Hexadecimal literals are prefixed with 0x. I love the idea that someone could get to this page and not already know that! Also this nicely highlights my pet peeve with assembly: add rd, rs1, rs2 # rd = rs1 + rs2 It's very difficult to remember which parameter is the destination etc. IMO it would be much nicer if assembly had just a little more syntax for that sort of thing. E.g. rd = add rs1, rs2 t0 = li 5…

That's a valid idea for RISC-V, but not always applicable. For example x86 `ADD` only accepts two operands, so `add rax, rbx` would add `rbx` to `rax` in place. `rax = add rax, rbx` would be a "faithful" translation, but `rax = add rbx, rcx` would be invalid (AFAIK there is still no three-operand version of scalar `ADD` in x86). `rax = add rbx` would be less redundant but way more confusing.

Another alternative is to mark the output in the operand position. Say, `add rd!, rs1, rs2`. I relate this to x86 `LEA` which is effectively an arithmetic operation but encoded like a load operation, hence a weird syntax `lea rax, [rbx + 42]` even though no memory access happens. Maybe that might be useful in the other way around.

Re: RISC-V Assembler: Arithmetic

#35
post #8

> ProTip: Hexadecimal literals are prefixed with 0x. I love the idea that someone could get to this page and not already know that! Also this nicely highlights my pet peeve with assembly: add rd, rs1, rs2 # rd = rs1 + rs2 It's very difficult to remember which parameter is the destination etc. IMO it would be much nicer if assembly had just a little more syntax for that sort of thing. E.g. rd = add rs1, rs2 t0 = li 5…

That's a valid idea for RISC-V, but not always applicable. For example x86 `ADD` only accepts two operands, so `add rax, rbx` would add `rbx` to `rax` in place. `rax = add rax, rbx` would be a "faithful" translation, but `rax = add rbx, rcx` would be invalid (AFAIK there is still no three-operand version of scalar `ADD` in x86). `rax = add rbx` would be less redundant but way more confusing. Another alternative is to…

> (AFAIK there is still no three-operand version of scalar `ADD` in x86)

Indeed, a 3-operand ADD is one of the extensions planned for Intel APX. But unless you need the output flags, an ordinary LEA suffices for adding two registers and storing the result in a third.

Re: RISC-V Assembler: Arithmetic

#36
post #32

Earlier quoted context omitted.

> Itanium fringe? You’re clueless Very fringe. A huge market failure. Hardware discontinued. Support removed in LLVM (2.6), and the Linux kernel (6.7). Still seems to be hanging on in GCC, though it was initially going to be deprecated in GCC 10. One of the very few ISAs I've never actually seen a real machine of, let alone used. And I've worked professionally on i960 (Stratus fault-tolerant computer), which not many…

That it was a failure is well known. But fringe, as in obscure (which is what I think is salient in this context)? I think that is misleading - that it has an official gcc backend to remove is a sufficient counterargument. Funny you mentioned PA-RISC and Alpha, as both were abandoned by HP and Compaq for it. Stupid (at least HP did backpedal, but not after burning a mountain of cash, it was to replace the PA), but no…

Well-known, yes, but fringe as in seldom seen.

Absolutely correct that mega-millions or billions went into it, both hardware and software, and that it FUD'ed many other ISAs to premature extinction.

It's not that hard to get an ISA into gcc and Linux -- you just need shipping hardware (or a convincing story that there will be) and someone to do the work. For example Andes (Taiwan) and C-Sky (China) both got their proprietary ISAs (nds32, c-sky) into GCC and the Linux kernel. And both switched to RISC-V not long after :_)

Re: RISC-V Assembler: Arithmetic

#37
post #32

Earlier quoted context omitted.

That it was a failure is well known. But fringe, as in obscure (which is what I think is salient in this context)? I think that is misleading - that it has an official gcc backend to remove is a sufficient counterargument. Funny you mentioned PA-RISC and Alpha, as both were abandoned by HP and Compaq for it. Stupid (at least HP did backpedal, but not after burning a mountain of cash, it was to replace the PA), but no…

Well-known, yes, but fringe as in seldom seen. Absolutely correct that mega-millions or billions went into it, both hardware and software, and that it FUD'ed many other ISAs to premature extinction. It's not that hard to get an ISA into gcc and Linux -- you just need shipping hardware (or a convincing story that there will be) and someone to do the work. For example Andes (Taiwan) and C-Sky (China) both got their pro…

Ok I’ll concede that’s a graveyard of obscurity in the gcc tree, but some group of people thought each one of those were worth the effort at some point, possibly delusionally. Do you need shipping hardware even? MMIX has a backend. Itanium doesn’t deserve this label though, shall it live forever in infamy.

Re: RISC-V Assembler: Arithmetic

#38
post #8

> ProTip: Hexadecimal literals are prefixed with 0x. I love the idea that someone could get to this page and not already know that! Also this nicely highlights my pet peeve with assembly: add rd, rs1, rs2 # rd = rs1 + rs2 It's very difficult to remember which parameter is the destination etc. IMO it would be much nicer if assembly had just a little more syntax for that sort of thing. E.g. rd = add rs1, rs2 t0 = li 5…

Assembly is meant to be 1:1 with machine code, which makes writing an assembler extremely easy as long as you know the architecture. Machine code doesn’t have things like equal signs, it’s literally just a series of bytes (an opcode and operands) If you want equal signs, use C

TI has an Assembly language for DSPs that feels like coding in C in SSA form.

It is an Assembly with equal signs.

Re: RISC-V Assembler: Arithmetic

#39
post #29
post #26

Earlier quoted context omitted.

Because from the CPU perspective, «+» is ambiguous as there is not one «addition» but many: - signed add - unsigned add - add and carry There are a few others in other ISA', then there are the operand sizes (byte, half-word, word, long word etc) and the «+» operator does not capture the operand size nor the specifics whereas - rd = rs1 addu8 rs2 makes the intention clear: «add the lower 8 bits from rs2 to rs1, don't…

Good post! ok, for rd = rs1 addu8 rs2 use rd = rs1 +u8 rs2 etc. The + stands out, more clearly indicating addition. (to me anyway) As for commutativity of +, it's not necessarily true. It depends entirely on what underlying operation + denotes. It's perfectly reasonable to use it for string concatenation, and that clearly isn't commutative. But if it's not in the case of an ISA, that's fine, just have the assembler r…

> rd = rs1 +u8 rs2

AMD 29k (its descendants are still alive) has two further ADD operations:

– ADDU – IF unsigned overflow THEN trap (out of range), and

– ADDCS – IF signed overflow THEN trap (out of range).

The ADD instruction family in the HP PA-RISC 2.0 is, of course, one of the best ones out there:

  ADD,cmplt,carry,cond r1,r2,t
Purpose: To do 64-bit integer addition and conditionally nullify the following instruction.

General register r1 and general register r2 are added. If no trap occurs, the result is placed in general register 1. The variable «carry_borrows» in the operation section captures the 4-bit carries resulting from the add operation. The completer, «complt», specifies whether the carry/ borrow bits in the PSW (the processor status word) are updated and whether a trap is taken on signed overflow. The completer, «carry», specifies whether the addition is done with carry in.

So, under a certain set of conditions, a PA-RISC «add» operation, other than yielding an add product, can:

– Can result in a trap on a signed overflow.

– Can nullify the following instruction.

An instruction mnemonic would like this:

  ADD,DC,TSV,C,
HP PA-RISC 2.0 also has an «add and branch» instruction, naturally, embellished with branch conditions, «cond»:

  ADDB,cond,n r1, r2, target
If «n» flag is set, the «add and branch» will also nullify the following instruction, e.g.

  ADDB,*
There are also an «add immediate left» instruction (a left shift and add a constant) and «halfword parallel add» (adds multiple halfwords in parallel with optional saturation).

How does one encode all of that with a «+» operator?

What about adding two decimals? The decimals are not used in modern CPU architectures, but they used to be a commonplace and were encoded by completely separate instructions.

The bottom line is: the assembly language is a slightly more human friendly (e.g. «add r1, r2, r3») interface into the bit code (e.g. a fictional opcode of «0xf500010203» for «add r1, r2, r3») and, consequently, into the internal CPU machinery and its state, and is not a high programming language nor a testamenet to the laws of mathematics.

Re: RISC-V Assembler: Arithmetic

#40
post #29

Earlier quoted context omitted.

Good post! ok, for rd = rs1 addu8 rs2 use rd = rs1 +u8 rs2 etc. The + stands out, more clearly indicating addition. (to me anyway) As for commutativity of +, it's not necessarily true. It depends entirely on what underlying operation + denotes. It's perfectly reasonable to use it for string concatenation, and that clearly isn't commutative. But if it's not in the case of an ISA, that's fine, just have the assembler r…

Obviously that doesn't generalize for opcodes with 0, 1, 3 or more input operands. As a concrete example, consider a fused multiply-add operation: `rd = fma rs1, rs2, rs3` is consistent, but how would you convert it to an infix notation?

  rd = rs1 * rs2 + rs3
It's no different from parsing if/then/else. Provided one assignment maps to one opcode, it's unambiguous.
Post reply on HN