Author Topic: which Effective Addressing Modes are essential for a HL language?  (Read 10571 times)

0 Members and 1 Guest are viewing this topic.

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
HL = High-Level, like C, Pascal, Ada ...

Effective Addressing Modes currently supported by our Arise-v2 CPU project:
- Address Register Direct: EA = reg
- Address Register Indirect: EA = mem(reg) (removed by Elisabeth)
- Address Register Direct with Postincrement: EA = reg; reg++
- Address Register Direct with Predecrement: reg--; EA = reg
- Absolute Immediate Addressing: EA = const

EA = Effective Address, what goes on the physical address bus.

There are other addressing modes, with index, scaled index, etc, ...

Now, since implementing them costs time and effort, I wonder if they are worth with.
Purpose of this: give a good support for a C-like compiler (still to be completed).

In short, I am wondering *where* (for which HL construct) and *which* addressing mode is really really useful; e.g. the RISC MIPS R2K does not even implement "Direct with Post/Pre increment/decrement Mode" ...  :-//
« Last Edit: November 08, 2018, 10:14:45 pm by legacy »
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #1 on: November 08, 2018, 08:14:56 pm »
Essential? only one...

Required for efficient implementation? most likely more than one.

mem(reg+const) is very useful if the reg is the equivalent of a stack frame pointer or base pointer.

I would have thought that postincrement/postdecrement are most likely not that useful, depending on if you allow byte or word addressing. On superscalar CPUs I guess you can do the fetch and the increment/decrement in the same cycle anyway.

Maybe see if you can find a copy of "Computer Architecture: A Quantitative Approach" by John L. Hennessy.

https://www.amazon.com/Computer-Architecture-Quantitative-John-Hennessy/dp/012383872X


PS. Is Pascal p-code still a thing?



Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26755
  • Country: nl
    • NCT Developments
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #2 on: November 08, 2018, 09:30:18 pm »
IMHO indexed (register + X) is very important. Think about stack frames (SP+x) or accessing members of structs.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #3 on: November 08, 2018, 10:23:45 pm »
mem(reg+const) is very useful if the reg is the equivalent of a stack frame pointer or base pointer.

Address Register Direct with Displacement Mode EA = mem(reg + sign_ext(const))
const = imm16bit

approved, and added  :D

I would have thought that postincrement/postdecrement are most likely not that useful, depending on if you allow byte or word addressing.

Arise-v2 allows { 8bit, 16bit, 32bit } addressing on the local bus.

therefore these two are
- Address Register Direct with Postincrement: EA = reg; reg+=OpSize
- Address Register Direct with Predecrement: reg-=OpSize; EA = reg

OpSize = { 1, 2, 4 }, according to { byte, word, long } accesses

However, there is a price to pay: it costs a couple of extra-circuits and 1 stage  :-//

Maybe see if you can find a copy of "Computer Architecture: A Quantitative Approach" by John L. Hennessy.

Thanks, Elisabeth should have a paper copy, somewhere.

PS. Is Pascal p-code still a thing?

Yup, it is  :D

You can still buy your copy of "MikroPascal Compiler" for modern MPUs (including ARM), it's cheap and funny. Besides, Pascal and Modula2 (sometimes also Oberon) are still used in universities, especially for teaching languages and compilers.
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #4 on: November 08, 2018, 10:32:58 pm »
IMHO indexed (register + X) is very important. Think about stack frames (SP+x) or accessing members of structs.

yup, it's simple and good for this!

Arise-v2 should be used to compute a lot of matrices, in fact, we also have a GTE unit (external to the SoC, it's a dedicated unit, and physically it's a second FPGA), hence I am wondering if EA = reg0 + reg1 * scale (immediate 16bit constant) could be really useful for easily accessing a cell in the matrix.


This addressing mode ( I don't know how it's called ... perhaps a sort of "Address Register Direct with Scaled Index" ?!?) costs:

- one multiplier unit, 32bit, unsigned
- one zero-extender, 32bit
- one adder, 32bit, unsigned
- six clock edges of wait (until EA is ready) in the load/store unit

What do you think?
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6173
  • Country: fi
    • My home page and email address
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #5 on: November 09, 2018, 12:27:17 am »
Now, since implementing them costs time and effort, I wonder if they are worth with.
Surprisingly enough, it highly depends on the number of registers available.

When there are only a few registers available (say, 80386 and compatibles), complex indirect accessing modes can keep the instruction count down, and avoid having to store temporary variables on the stack.

If you have lots of registers, and a fast "load-effective-address" instruction (again, similar to 80386), so that most of those registers can be used as pointers, it turns out that those complex indirect addressing modes aren't that useful anymore.

The next problem is finding a compiler that generates efficient code for either case.  As an example, GCC is not particularly good at register use and reuse; even in optimized (-O2) code, you often see register moves and assignments that are completely ... stupid.

This means that the answer to the underlying question ("which EA modes ..") is something annoying like "it depends on what addressing modes your compiler needs, to generate efficient code".

I know that GCC generates slightly better assembly from pointer-based C than the equivalent expressions using array indexing.  Fortran (say F95 and later) is obviously different, as it has an efficient way of expressing array slicing.

All this waffle means that in my opinion, you should consider writing e.g. a GCC port for the tentative instruction set architecture, and examine the code generated in each case, for some typical constructs.  Yeah, I know; I'm not being particularly helpful here, sorry.

(I need to go look at Arise-v2 in detail before commenting again, I guess.)

I am wondering if EA = reg0 + reg1 * scale (immediate 16bit constant) could be really useful for easily accessing a cell in the matrix.
The scale is not always a constant, so do consider EA = reg0 + reg1 * reg2 instead. (Not only is the instruction shorter, but it is much more versatile this way.) Also, all of those could be negative as well.

That said, I do believe that if you had a fast (whatever your minimum instruction duration is) fused multiply-add instruction (regN = regA + regB * regC) and/or related load-effective-address instruction (regN = imm32 + regA<<imm5 + regB * regC) for signed integers, that would do just as well. If simplifying the addressing modes would allow that, I'd definitely go for it.

In general linear algebra (say, the same niche BLAS/LAPACK or GSL target), using a separate signed stride for both row and column advancement allows advanced features not supported by even GSL. I have an outline here on stackoverflow in C. Unlike in GSL, "views" are first-class matrices, indistinguishable from the matrix they view to; this not only simplifies code, but it makes it easier for "non-professional programmers" (scientists) to write efficient linear algebra code.

(It's just that BLAS/LAPACK/ATLAS/GSL have such a devoted following that even showing practical examples of a better, easier, and more efficient code is not enough to budge the set of scientists I've worked with. Meaning no funding, and therefore no push on my part.)

Another set of users work with very large sparse matrices, but the known implementations do not really need any special addressing modes for those. (These appear in e.g. materials physics, where the matrix contains the locations and velocities of each atom in the cluster or lattice, and the eigenvalues provide the phonon frequencies.)
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4196
  • Country: us
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #6 on: November 09, 2018, 01:05:14 am »
Quote
it highly depends on the number of registers available.
Yeah, that.  I would much rather have multiple (preferably all) registers be usable as simple index registers than have a single index register with lots of modes.
RISC philosophy says it's faster and easier (for both hardware and compiler authors) to leave out fancy addressing modes and just do the math manually.
But... An Atomic PUSH and POP capability is pretty important.
On modern RISC processors, I really miss "immediate" addressing (on PDP11, this was done with post-incremented indexing off of the PC register.  That probably wrecks havoc with pipelines...)
TI's MSP430 uses some non-sensical address modes (anything off of STATUS?) to implement some common constants.  Cute.
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #7 on: November 09, 2018, 06:06:42 am »
https://llvm.org/docs/LangRef.html#load-instruction

EDIT: and of course, the corresponding "store" instruction
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6173
  • Country: fi
    • My home page and email address
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #8 on: November 09, 2018, 08:55:34 am »
But... An Atomic PUSH and POP capability is pretty important.
Fully agreed. Also either atomic compare-exchange or load-linked store-conditional, for lock support. But those are specific instructions, not general arithmetic instructions with addressing modes.

on PDP11, this was done with post-incremented indexing off of the PC register.
Also on AMD64 for position-independent code; one can offset off %rip, which during execution of such an instruction, is the address of the beginning of the following instruction. Just recently posted a freestanding C example on AMD64 on Linux about that.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4196
  • Country: us
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #9 on: November 09, 2018, 10:06:06 am »
Quote
Quote
An Atomic PUSH and POP capability is pretty important.
Fully agreed. Also either atomic compare-exchange or load-linked store-conditional, for lock support
Well, yeah.  But in this case I was pointing out that some instructions are going to need to do that whole pre/post increment/decrement indexed addressing, and it seems to be a shame to make that work ONLY for push/pop. (although I guess that ARM v6m (Cortex M0) does exactly that.   Grr.)
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #10 on: November 09, 2018, 11:01:56 am »
Surprisingly enough, it highly depends on the number of registers available.

32 registers + PC: 30 are usable, 2 are reserved (e.g. r0 always returns 0x0000.0000, r1 is the stackpointer)

fast "load-effective-address" implemented instructions are:
- Address Register Direct: EA = reg
- Absolute Immediate Addressing: EA = const

these take 1 stage, 1 writeback, and 1 clock edge to evaluate EA, besides all registers can be used as source and target

The next problem is finding a compiler that generates efficient code for either case

We have to write the compiler, currently, there is only an assembly compiler to "try" the ISA (if enough consistent, etc ...)  :D

I am wondering if EA = reg0 + reg1 * scale (immediate 16bit constant) could be really useful for easily accessing a cell in the matrix

The scale is not always a constant, so do consider EA = reg0 + reg1 * reg2 instead. (Not only is the instruction shorter, but it is much more versatile this way.) Also, all of those could be negative as well.

for what is it more versatile than the above?

if you had a fast (whatever your minimum instruction duration is) fused multiply-add instruction (regN = regA + regB * regC) and/or related load-effective-address instruction (regN = imm32 + regA<<imm5 + regB * regC) for signed integers, that would do just as well. If simplifying the addressing modes would allow that, I'd definitely go for it.

Arise-v2 supports MAC for System of Linear Equations, FIRs, and IIRs algorithms. The MAC unit costs more LEs in the FPGA than a simple unsigned-multiplier, and the MAC takes 12 clock edges to compute.

As every RISC machine, the ALU stage precedes the Load/Store stage, therefore the ALU may use the MAC to evaluate the EA for the Load/Store.

Technically even the MAC can be used, but it has cost (the design needs to be modified a bit, therefore retested from the belt down), and again I miss where it's really useful?

Can you give me an example of a C structure where this makes a good deal?

In general linear algebra (say, the same niche BLAS/LAPACK or GSL target), using a separate signed stride for both row and column advancement allows advanced features not supported by even GSL. I have an outline here on stackoverflow in C. Unlike in GSL, "views" are first-class matrices, indistinguishable from the matrix they view to; this not only simplifies code, but it makes it easier for "non-professional programmers" (scientists) to write efficient linear algebra code.

Here I don't follow you

The GTE unit performs
- matrix rotations
- matrix scaling
- matrix translation
- pixel color interpolation (up to 3 points, triangle rastering)
- polyline drawing (up to 4 points)

All of this is made on hardware by the GTE unit for which the CPU (Arise-v2) only needs to pass commands and data; however Arise-v2 also needs to manipulate matrices and linear system of equations, whose algorithms are interactive approached and massively use the MAC, since, at each step, the iteration is a sort of A[ i+1 ] = A[ i ] + B[ i ]*b

rt = MAC (r0, r1, r2)
rt = A[ i+1 ]; r0 = A[ i ]; r1 = B[ i ]; r2 = b

Accessing a matrix-cell is something like "coll_i * (sizeof(row)) + row_i", which can be mapped into the hardware directly, EA = r0 * imm16 + r1, r0=coll_i, r1=row_i

I don't see why you are suggesting to use a register for the scale, and a sint32_t scale.

Just to hve shorter instructions?  :-//
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #11 on: November 09, 2018, 11:19:43 am »
Atomic PUSH and POP are implemented by
- Address Register Direct with Postincrement: EA = reg; reg++
- Address Register Direct with Predecrement: reg--; EA = reg
by using the stack pointer SP for the "reg"

These two have the cost of a second writeback stage, which is one of the reasons why MIPS-R2K" doesn't have them. But my team believes they are a MUST.

I don't believe Arise-v2 will ever have a multitasking OS, however CAS and TAS (semaphore-instructions) are useful because the GTE and the CPU share a dual port ram, with a couple of hardware semaphores; they don't have any impact on the current EA circuit, they need more dedicated states for the read-and-modify cycle on the bus.
« Last Edit: November 09, 2018, 05:24:36 pm by legacy »
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6173
  • Country: fi
    • My home page and email address
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #12 on: November 09, 2018, 02:33:15 pm »
I hadn't read your Hackaday.io project page, so I misunderstood the context.

Can you give me an example of a C structure where this makes a good deal?
Accessing a pixel canvas, where the origin address and width are variables, i.e.
Code: [Select]
uint32_t *canvas;
uint16_t width, row, col;
canvas[row*width + col] = ...;
the address calculation is essentially canvas + 4*col + 4*row*width . Even when canvas and width are fixed, you are still left with imm32 + 4*regA + 4*imm16*regB

Now that I understand that the matrix stuff is related to computer graphics, regA + 4*regB + 4*regC*regD with 15-bit unsigned regB, regC, and regD would do just fine. But, because most algorithm access pixels sequentially, such random access is probably not needed at all.

Here I don't follow you
I hadn't read your Hackaday.io project description, so was off in the woods. (I've always wanted a real beefy FPGA to play with, to implement certain classical potential models in hardware, to see how/if I could boost simulation speeds. So I was projecting there a bit..)



For antialiasing lines, curves, and edges in general, I'd really want an addressing mode for loads and stores where only the upper 16 bits of col and row registers (ignoring the highest bit) were used in the address calculation, with a fixed multiplier of 4. It would mean that if you have a Q15.16 row and column coordinates in 32-bit registers, you could use them directly in addressing the pixel itself: EA = reg32/imm32 + 4 * ((regC >> 16) & 32767) + 4 * reg15/imm15 * ((regR >> 16) & 32767). (Noting, of course, that 15×15-bit multiplication shifted left by two bits is at most 32 bits.)

That high subpixel precision may sound overkill, but it allows pixel-precise lines over the entire coordinate range, and should be enough to evaluate e.g. Bézier curves without converting them into lines. Things like triangle filling with edge antialiasing is also computationally cheap; and you don't need Bresenham anymore at all. You do need a 31-bit to 31-bit (unsigned) division that essentially does (regA << 16) / regB to calculate the slope. But it works for lines starting and ending at subpixel coordinates just fine.

Let me know if you want some example C code to play with.
« Last Edit: November 09, 2018, 02:34:57 pm by Nominal Animal »
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3137
  • Country: ca
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #13 on: November 09, 2018, 03:47:04 pm »
There's no difference for the HL compiler. It can emit a series of commands just as easy as a single command.

The important thing is how you encode your instructions. If you have fixed-length instructions, unless your instructions are wider than the address bus, encoding "Absolute Immediate Addressing" consumes lots of code space without much benefits. The small things, such as auto-increments/decrements, take very little of code space, and do not take any extra time, and require very little extra logic, so they're easy. However, taking advantage of them will take extra work when you write the compiler. Indexing is also easy if you can handle several additions within a cycle, and it also doesn't take much code space. It greatly simplifies access to arrays.

The compiler implementation will be easier if you do not to make any exceptions - such as register A can only be used for this, while B can only be used for that etc.

If you're going to use dynamic linking, think about addressing modes which would support PIE (position-independent execution). Otherwise, you may create extra work for the compiler.

Another thing which is important for the HL compiler is stack frames. If your compiler is going to use them then it's a good idea to include provisions for this. For example, you may include addressing relative to a dedicated frame pointer.
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #14 on: November 09, 2018, 05:20:58 pm »
auto-increments/decrements, take very little of code space, and do not take any extra time, and require very little extra logic, so they're easy

this takes
- 1 extra writeback stage to update the auto-incremented/decremented register in the RegisterFile
- 1 glue stage
- 1 extra cycle

Easy? Well, it's just 30 lines of VHDL, but this breaks the simple design of a machine like MIPS, in fact, the MIPS R2K doesn't have any of these instructions. We can add them, and we will, but first I wanted to understand *IF* it's a good deal, and which is the real gain!

It seems that the only real GOOD motivation gets point for the atomic push/pop.

We are in a democracy team, four dudes, and a girl; and Elisabeth (the project leader) wants them, I am core-design, and I am still not sure it's a good idea, but other guys have voted to have them, therefore let's have it  :D

The compiler implementation will be easier if you do not to make any exceptions - such as register A can only be used for this, while B can only be used for that etc.

Yup, precisely. One of the goals is getting stuff prepared for the simplest Compiler implementation possible.
« Last Edit: November 09, 2018, 05:22:55 pm by legacy »
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3137
  • Country: ca
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #15 on: November 09, 2018, 06:37:51 pm »
this takes
- 1 extra writeback stage to update the auto-incremented/decremented register in the RegisterFile
- 1 glue stage
- 1 extra cycle

If your registers are implemented as a memory file which can only be accessed through a single access port, then, of course, including auto increments and decrements is not a good idea, even for stack. In such case, auto increments will not give you much of a gain compared to incrementing in a separate command.

If, on the other hand, your register file is double (or triple) port, you can auto-increment and write simultaneously with the main operation without any side effects.

If your registers are just sets of flip-flops, you can read or update all of them as you wish without interfering with each other, but this is much more logic, and probably is not practical for CPUs with 32 registers.

Yup, precisely. One of the goals is getting stuff prepared for the simplest Compiler implementation possible.

Having auto-increments/auto-decrements may make the compiler more complex, unless you want to limit the use of auto-increments to trivial cases such as "i++".
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #16 on: November 09, 2018, 07:23:54 pm »
If your registers are implemented as a memory file which can only be accessed through a single access port

This is the case. Like in the MIPS R2K design.

Having auto-increments/auto-decrements may make the compiler more complex, unless you want to limit the use of auto-increments to trivial cases such as "i++".

Why?

Consider a thing, expressions are handled as RPN, for which auto-increments/auto-decrements should be useful. I guess :-//


RPN = Reverse Polish Notation
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3137
  • Country: ca
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #17 on: November 09, 2018, 08:23:30 pm »
This is the case. Like in the MIPS R2K design.

You may consider dual-port memory. It shouldn't complicate the design much.

Having auto-increments/auto-decrements may make the compiler more complex, unless you want to limit the use of auto-increments to trivial cases such as "i++".

Why?

Consider a thing, expressions are handled as RPN, for which auto-increments/auto-decrements should be useful. I guess :-//


RPN = Reverse Polish Notation

Imagine usual code patterns, such as:

Code: [Select]
for(x = 0; x < z; x++) {
  lots of code here with accessing various arrays with x.
}

If you want to insert the auto-increment here, you need to analyze the whole body of the loop and find the last-executed array access where you need to pin your auto-increment. With lots of ifs it will require some work and may not be possible.

Or this:

Code: [Select]
z = a[x] + b[x];
// 20 unrelated lines here
x++;

You can use auto-increment here, but the C coder can't. By C standard, adding "++" to any x in the expression may harm another "x". So, the coder will put "x++" at the end. The compiler must find it and convert to auto-increment.

If you don't want to deal with cases like these, all you have left is the cases where the C coder combined "++" with some sort of access to the variable. For some reason, many of them don't do this and prefer standalone "x++;"  statements.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3137
  • Country: ca
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #18 on: November 09, 2018, 10:14:20 pm »
Quote from: legacy link=topic=149881.msg1953853#msg1953853
... you can read two registers in parallel per cycle, but only write one register per cycle! For two registers to be updated, and considering FPGA uses BRAM which is of the same kind of above, you need to write-cycles done on two different stage of the FSM!

Spartan-6 (and -7) has true dual port BRAM where both ports can be written at the same time.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14306
  • Country: fr
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #19 on: November 10, 2018, 12:54:36 am »
Consider a thing, expressions are handled as RPN, for which auto-increments/auto-decrements should be useful. I guess :-//

Just a quick note, but having auto-incrementing with a step of only 1 is only marginally useful especially if you have other sophisticated addressing modes such as those you suggested (with scaling and such), so would you allow increments different than 1?
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #20 on: November 10, 2018, 10:03:37 am »
Just a quick note, but having auto-incrementing with a step of only 1 is only marginally useful especially if you have other sophisticated addressing modes such as those you suggested (with scaling and such), so would you allow increments different than 1?

Arise-v2 allows { 8bit, 16bit, 32bit } addressing on the local bus.

therefore these two are
- Address Register Direct with Postincrement: EA = reg; reg+=OpSize
- Address Register Direct with Predecrement: reg-=OpSize; EA = reg

OpSize = { 1, 2, 4 }, according to { byte, word, long } accesses
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14306
  • Country: fr
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #21 on: November 10, 2018, 11:21:13 pm »
Alright. This is useful for consecutive accesses of course, which are frequent for moving/copying blocks of data for instance.

I'm thinking that combining postincrement/predecrement with your "scaling" access modes would be much more generic and useful in various cases, such as:
EA = reg0 + reg1 * Scale; reg1++

an increment of 1 only would be sufficient due to the scale factor. That would cover a  much larger number of cases. That may be a bit too complex though as far as addressing modes go? ;D
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4001
  • Country: nz
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #22 on: November 11, 2018, 01:28:29 am »
Now, since implementing them costs time and effort, I wonder if they are worth with.
Purpose of this: give a good support for a C-like compiler (still to be completed).

Compiler guy here. It's almost certainly not worth the extra complexity.

ARM has a lot of complex addressing modes. RISC-V (like MIPS) has only "EA = register+offset" and, even more, reduces the offset from 16 bits to 12 bits. In compensation, LUI and AUIPC are increased from 16 to 20 bits, so you can still load anything in a 32 bit addressing range (either absolute or PC relative) in two instructions.

Despite the lack of addressing modes (no scaled offset, no auto-increment, no register+register), RISC-V programs come in at essentially identical size to Thumb2 programs, and also have slightly better benchmark numbers (Coremark, Dhrystone, whatever you want) than equivalent ARM implementations.

Modern compilers such as gcc or llvm do a great job of removing complex addressing from loops and turning it into simple increments.

Note: this does depend on using modern compilers. If you're going to write your own compiler then it may be different as it's a *lot* of work. I'd say it would be crazy. You're much better off writing a back-end for gcc or llvm.

Or, just base your CPU on an existing instruction set that there are already compilers and software for. You can always add your own extensions for the unique aspects.
 
The following users thanked this post: Nominal Animal

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #23 on: November 11, 2018, 07:55:15 am »
Note: this does depend on using modern compilers. If you're going to write your own compiler then it may be different as it's a *lot* of work. I'd say it would be crazy. You're much better off writing a back-end for gcc or llvm.

  • gcc was the first choice we evaluated, but it is not good to deal with; especially at the machine-layer level, it's so poorly documented that the closest you look at the code the most it drives you crazy since the code is really a crap. Besides, GNU guys at gcc are not prone to help, they are snob and clinky with the very bad attitute of thinking they are special-ones, like if ones out of their group were so lacking in intelligence that they cannot grasp their simplest concepts, hence in our group we have recently voted to stay away from gcc in order to safeguard the mental and emotional health
  • llvm is good stuff! neat and clean, written in C++ as a library, guys are friendly and writing the machine-layer looks well documented and "sane"
  • lcc is a good didactical compiler, which makes it more interesting for Arise-v2, the code comes with a book, and it's neat and clean, and good at showing the theory and the practice

llvm and lcc were to good candidates, but we already have a partially working compiler (used to generate the assembly for RPN expressions and simple while-loops for HDL-testbench-ing), and we don't want to implement the common C-language; in fact, Arise-v2 comes with what we call "SafeSmallC", which is not exactly C, it's similar but not equal, and it's a (strongly typed designed) subset.

The world is already plenty of C compilers, and ISAs and MPUs, CPUs, DSPs and tons of things for every taste. Arise-v2 is not intended for this.
« Last Edit: November 11, 2018, 08:03:40 am by legacy »
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4001
  • Country: nz
Re: which Effective Addressing Modes are essential for a HL language?
« Reply #24 on: November 11, 2018, 10:15:34 am »
You're right that gcc is probably best avoided.

I think you should go with llvm. As you say, it's well written and the people are friendly. Also, it's quite careful to *not* be tied in to C. A lot of languages use llvm as the optimiser and code generator.

If you want an optimising compiler (and you do if you want to efficiently have only a simple addressing mode) then go with llvm.

If you go with a simple compiler that doesn't know how to do loop induction variables, strength reduction/scalar evolution, code motion out of loops then you might want to include addressing modes such as base + scaled offset. It's more hardware, more redundant repeated calculations, more energy consumption but it's easier to do simple compilation of ASTs to.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf