Constant appearing inline in .text instead of loading from memory

assembly language commands list pdf
assembly language instruction set
assembly language instruction set pdf
assembly language instructions examples
assembly language instructions in computer organization
assembly language program for a=(b+c)*d
constant declaration in c++
mips assembly language programming examples

We are basically working in a sparc architecture.and using gcc to compile our code.

We are using some constants in our code, but compiler instead of allocating memory for some of these constants is instead optimizing and making it part of the code

for example

cHello : CONSTANT INTEGER_16 := 16#FFFE#;
a = cHello [ cHello is a constant ];

The assembly is as follows.

set 16#FFFE#, %g1
sthw %g1, [%g2]

compiler is putting value of cHello inline to code(.text) instead of loading from memory.

How to make compiler load constant from memory instead of putting them inline

Edit: The language is Ada

Why do i care:

Here is the problem, we have an embedded system, where our code is actually running from RAM, and we would like to have the constant modifiable. We don’t want to make it .data, as then we will have two copies of it; at power on they are copied to Variable RAM area. So constant are better in this case. Plus the RAM from where we are executing is LOCKED from writes. So we unlock it and then write to Code RAM.

It is working as expected. Constant variables are being allocated in the .text (or any const section), however you want to use RAM as flash, being the RAM a valued possesion. Anyway, if you do want to use the RAM to allocate constant values, you can create a new section (.myownconst) in RAM through the linker and declare your const variable as __attribute__((section(".myownconst")))

Constant appearing inline in .text instead of loading from memory, is putting value of cHello inline to code(.text) instead of loading from memory. How to make compiler load constant from memory instead of putting them inline  cHello : CONSTANT INTEGER_16 := 16#FFFE#; a = cHello [ cHello is a constant ]; The assembly is as follows. set 16#FFFE#, %g1 sthw %g1, [%g2] compiler is putting value of cHello inline to code(.text) instead of loading from memory. How to make compiler load constant from memory instead of putting them inline. Edit: The language is Ada . Why do i care:

The syntax of this answer is going to assume a recent (GNAT, Ada2012) compiler, but I’ve no doubt you could do the same with pragmas.

From observation, GNAT will make the constant into an immediate literal if it can see it.

GNAT won’t let you make the variable both constant and volatile.

The only way I’ve found to force the constant to be fetched from store at all is to fool the compiler by making it import the variable:

with Interfaces;
package Prakhar_Constants is
private
   Chello : constant Interfaces.Integer_16 := 16#7FFE#
   with
     Export,
     External_Name => "constant_chello";
end Prakhar_Constants;

and then

with Interfaces;
with Prakhar_Constants;  -- so the binder will know to include it
procedure Prakhar is
   Chello : constant Interfaces.Integer_16
   with
     Import,
     Convention => Ada,
     External_Name => "constant_chello";
   A : Interfaces.Integer_16;
begin
   A := CHello;
end Prakhar;

I don’t think you need bother with volatile (unless you’re going to change the "constant" mid-execution).

[PDF] Assembly Language, As shown in the figure above, one register contains 32 bits (1 word) and one will make the CPU load the value stored at memory address [100+r2] into In general, immediate instructions will have two registers and one constant as 20. In line 23, the .text directive tells the assembler that what follows is a code segment  How to Fix: Constant Spinning Cursor (Circle) in Windows. Below I'll explain how I went about resolving the issue. The first thing I did was right click on the task bar and selected "Task Manager". Once Task Manager was loaded, I clicked the "more details" button near the bottom left; this made the Task manager window bigger.

You could try an aliased constant:

cHello : aliased constant Interfaces.Integer_16 := 16#FFFE#;

Different ways to declare variable as constant in C and C++ , Hence they only define the symbolic name of constant. Therefore if you need a constant variable with a specific memory address use either 'const' or 'constexpr'​  Hi there, I have this problem with my computer after updating windows 7 (Home Premium 64bits) After the update is installed and my computer restarted, the text are replaced with symbols, triangles, and other characters instead of legible text.

I think you should define the value of the constant in a stand-alone asm or C file. This is a guaranteed way to stop the compiler inlining the value anywhere even with link-time optimization, without using anything as inefficient as volatile. i.e. the Ada compiler never sees the value of the constant at all, in any source file.

I don't know Ada, but the C equivalent would be extern const int my_const; and then in a separate constant.S file use .section .rodata / my_const: .long 0x12345. Or use a custom section and a linker script to get your modifiable constants placed somewhere specific in your binary.

For more about interfacing Ada with with C or asm, see https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gnat_ugn/Interfacing-to-C.html. It has examples of importing and exporting symbol definitions to/from C. (And the mapping between C and asm is very simple, so you can just tell Ada that it's C even if you create the object files using asm.)

My_Num : Integer;
pragma Import (C, My_Num, "Ada_my_num");

Ideally you can declare My_Num in a way that the Ada compiler knows it's a constant. This declares it as a plain global (with an external definition using the Ada_my_num C symbol name.)

This is pretty similar to what @Jose's answer is suggesting, except using stand-alone asm to hide the value from the compiler.


You want the compiler to be able to optimize as much as possible. i.e. to assume that the value of this "variable" doesn't change during the lifetime of the program, so it can load it into a register at the start of a function and assume that calls to non-inline functions can't change it. Or to avoid redoing calculations involving it (CSE), so if your source code has a * my_const both before and after a function call, it can save the result in a register instead of reloading the constant from memory and redoing the multiply after the function call.

This can't happen if the compiler thinks it's an ordinary global variable with unknown value; it would have to assume that the function call might have changed the value of any global variable.

But if you used an ordinary global variable and assign a value to it anywhere the Ada compiler can see, then whole-program link-time optimization could propagate that value to other places, or even bake it into other constants. (e.g. if you ever do a += 2 * my_constant, you could have 2*my_constant hard-coded somewhere in your asm output).

(e.g. if you compile+link with -flto to let the compiler optimize between compilation units. IDK if GNAT can do this the same way the C front-end can, but hopefully it can.)


Why the compiler does this: because it's more efficient, of course!

Loading a value from static data in memory typically takes multiple instructions to generate a 32-bit address (on a fixed instruction-width ISA like SPARC); with the same number of instructions you could have created an arbitrary 32-bit constant in a register directly. ALU instructions are typically cheaper than loads, and can't miss in cache.

Small constants are even more efficient, and can be used as a single immediate operand for add, or, and, or whatever.

Constant folding and constant propagation after inlining is a major way that the asm version of a program can do less work than the source. e.g. 5 * my_const can be done at compile-time if the compiler knows the value of my_const. (So it could generate that in a register directly, if needed, instead of loading my_const and using a shift/add.)

Some generic function might check if(x>0), but the compiler might be able to prove that's always true in one place where the function inlines, if it knows something about the values of constants. (That's a value-range optimization).

Denying your compiler the value of a constant can definitely make your code less efficient, depending on how you use the constant.


Example compiler output. (I assume you can write equivalent Ada which GNAT's / gcc's SPARC back-end will optimize similarly to what clang/LLVM -target sparc does). The point of this is to illustrate the difference between a constant of unknown value vs. a known constant:

(From clang6.0 -O3 -fomit-frame-pointer -target sparc on the Godbolt compiler explorer)

const int my_const1, my_const2;
static const int my_static = 123;  // a small constant that works as an immediate

int foo(int x) {
    return x + my_static;

}

    retl
    add %o0, 123, %o0         # branch-delay slot


int one_constant(int x) {
    return x + my_const1;
}

    sethi %hi(my_const1), %o1
    ld [%o1+%lo(my_const1)], %o1
    retl
    add %o1, %o0, %o0

The latter is pretty obviously less efficient. It seems that clang doesn't know if / when %hi(my_const1) and %hi(my_const2) are the same, so it uses another sethi for each static location. Ideally the compiler could use the same reference point for multiple accesses inside a large function, but that doesn't seem to be the case for clang/LLVM. Godbolt doesn't have SPARC gcc, so I couldn't try that easily.

[PDF] MSP430 Assembly Language Tools, Memory Allocation Shown in and . Some targets allow content other than text, such as constants, in .text sections. .text section. Contains symbol that lets you refer to the load-time address, rather than the run-time address, see the .label directive. Supports macros, allowing you to define macros inline or in a library  These are called gremlins and they are usually caused because whichever program is putting the quotes in is using the actual pretty / curly / smart quotes instead of the proper HTML entities. The fonts don't display right or don't have those characters in them and instead produced the funny symbol.

[PDF] TMS320C28x Assembly Language Tools v16 , Memory Allocation Shown in and . Some targets allow content other than text, such as constants, in .text sections. .text section contains attribute that tells the loader to perform initialization directly and not to load the .cinit section into memory. Supports macros, allowing you to define macros inline or in a library  Knowledge Base. Get step-by-step help and tips on how to use and get the most out of your Constant Contact tools.

Extended Asm (Using the GNU Compiler Collection (GCC)), If you use the inline qualifier, then for inlining purposes the size of the asm It is a combination of fixed text and tokens that refer to the input, output, and goto asm supports operand modifiers on operands (for example ' %k2 ' instead of and y both appear twice in the asm parameters, once to specify memory accessed,  When executing the procedure from the client, use RPC rather than the cursor API. With ODBC, avoid the Transact-SQL statement EXECUTE, instead specify the name of the procedure directly. When executing the procedure from a Transact-SQL batch or another stored procedure, avoid using a cursor with the natively compiled stored procedure.

[PDF] Using GHS Compiler with RH850, Inline functions, that are only called once. 2.2.2. CPU Architecture dependent settings. •. Use SDA memory optimization o no base register load  In this video today we will see why you are not getting text message sound even though you have enabled it. Please like, share and subscribe to my YouTube channel for more tips and tricks. Now let

Comments
  • inline as an immediate, you mean? I doubt the compiler has options to make it generate worse code, and getting a small constant into a register with one ALU instruction is probably always better than a load. SPARC immediate constants can be up to 11 bits, or the high 21 bits for sethi.
  • well yes, but some inlines are like, is generating set CONSTANT, %g1 type of instruction. It just saves one extra load instruction. I guess i have to either make it volatile or declare another section !
  • You didn't specify a programming language when asking your question. I am not sure if my answer is applicable to Ada at all. For the next time, always without failure specify the programming language you are programming in. I have deleted my answer because it does not apply to Ada.
  • That is either an XY problem or you missed relevant information. Why do you care at all how the code is optimised? In general one should not, except for hardware peripheral registers in which case you have to use language-specific (or even compiler-specific, IDK Ada) features. Currently your question is unclear.
  • @fuz: Your answer doesn't apply to C either, depending on the circunstances the compiler is very well free to change the behaviour. Also C does not have constants (other than what's commonly called "literals") at all. And fyi, it's "abstract machine", not "virtual machine".
  • There is no guarantee where and how objects or even literals are accessed. Using sections does not change that, they are just used by the linker. But that does not mean accesses to const qualified objects are not e.g. converted to immediate operands in the generated code.
  • @Olaf: Right, so you declare it as non-const and simply don't write any code that modifies it. Then use linker tricks to put it where you want it. (And then check that link-time optimization didn't notice that and treat it as const...) The OP is doing embedded development with a specific known toolchain, so a solution that happens to work there is probably sufficient, as long as it's not likely to break from just source changes, only from major compiler behaviour changes. I don't think there is any language support for reading once from mem, but assumed not to change across func calls.
  • @PeterCordes And what would that change? The compiler is still free to do what it wants within the rules of the language. Something like "The OP is doing embedded development with a specific known toolchain" is just calling for trouble on maintenance/extending. Embedded software is often maintain for decades which makes your advice even more dangerous. As I wrote, the question is almost certainly an XY problem.
  • @Olaf: I added an answer that avoids letting the Ada compiler see the value at all, while hopefully minimizing the efficiency impact: put the value in a separately-compiled asm source, or C that you compile without LTO.
  • wow! exactly what I wanted. " GNAT will make the constant into an immediate literal if it can see it", this statement is what I was searching in the reference manual all over !. Is it mentioned in some document ? @simonwright
  • stackoverflow.com/questions/50407178/… @simonwright Can you help me with this observation too ! I cant make head or tails of why would compiler do that for some constants ! and this behavior for some constants.
  • I don’t know why GNAT makes the constant into an immediate literal if it can see it; you’d have to ask the compiler people. But it probably has to do with caching (the immediate literal may be in the instruction cache??) It was just an observation, anyway, not knowledge!)