3 ms·
> integer overflow detection What are you looking for here? Carry and overflow flags were explicitly not included because of the additional cost for OoO proces
by camel-cdr 2y ago
> integer overflow detection
What are you looking for here? Carry and overflow flags were explicitly not included because of the additional cost for OoO processors.
Let's compare overflow detection on RISC-V vs aarch64:
unsigned 64-bit:
add: RV: add+bltu Arm: adds+bcc
sub: RV: sub+bltu Arm: subs+bcs
mul: RV: mulhu+mul+beqz Arm: umulh+mul+cbz
unsigned 32-bit:
add: RV: addw+bgeu Arm: adds+bcc
sub: RV: subw+bgeu Arm: subs+bcs
mul: RV: mul+slli+beqz Arm: umul+cmp lsr 32
signed 64-bit:
add: RV: add+slt+slti+beq Arm: adds+bcc
sub: RV: sub+slt+slti+beq Arm: subs+bcs
mul: RV: mulh+mul+srai+beq Arm: smulh+mul+cmp asr 63
signed 32-bit:
add: RV: addw+add+beq Arm: adds+bvc
sub: RV: subw+sub+beq Arm: subs+bvs
mul: RV: mul+sext.w+bew Arm: smul+asr+cmp asr 31
So it's on par for unsigned, and takes two additional independent instructions for signed 64-bit and one for signed 32-bit.
For teaching, using unsigned XLEN-bit values by default is probably a good idea anyway.
> indexed addressing
I'm not sure how much this actually matters in practice.
It's nice when you access multiple arrays at the same index, such that you only need to implement one index instead of every pointer.
Such loops are often vectorized, and the indexed loads become useless, once you read two values from an array index, e.g. an array of structs.
Edit: removed measurements, because I'm not sure they are correct, might add back later.
- adrian_b 2y agoThe cost of providing carry and overflow is absolutely negligible in any CPU and even more so in an OoO CPU, which is many times more complex. If you mean that if the flags are not stored in a general-purpose register, which is a possible choice, but it requires an extra register file write port, but in a dedicated flags register, like in x86 or ARM, then the flags register must also be renamed to allow concurrent operations, like any other register, this is a minor complication over having register renaming for all other registers. What is extremely expensive is not having overflow and carry in hardware and having to implement software workarounds that require several times more instructions. When loops are vectorized or you have an array of structures, this does not change anything, you still use the same indexed addressing (or auto-incremented addressing in ISAs that have it). Perhaps you think about scaled indexed addressing, which may not always work for an array of structures, but in such cases you just use simple indexed addressing, with the scale factor 1. Without either indexed addressing or auto-incremented addressing you need an extra addition instruction for each memory access, which increases the code size and it limits the execution speed by occupying an extra execution port. Because of this, the highest-performing RISC-V implementations have added non-standard ISA extensions for indexed addressing, but such extensions are still rather awkward because the base instruction encoding has not been thought for allowing indexed addressing, so the extensions must use a quite different encoding that must be squeezed in a limited encoding space.