1826498 Members
1717 Online
109692 Solutions
New Discussion

Getting IA64 reg R8

 
SOLVED
Go to solution

Getting IA64 reg R8

Hi,

Does anyone know how I can get the value of the R8 (similar to R0 on Alpha) register on IA64 ?

The VMS C compiler does not like __getReg(_IA64_REG_R8). _IA64_REG_R8 does not exists in the headers and the value of is _IA64_REG_R8 is not allowed either.

None of the register names here include R8 ?
http://h71000.www7.hp.com/commercial/c/docs/5492profile_031.html

Example...
$ ty asm.c
#include

int main(void)
{
long long r;

#define _IA64_REG_R8 1032 ///< R8
r = __getReg(_IA64_REG_R8);
return 0;
}
$ cc asm

r = __getReg(_IA64_REG_R8);
........^
%CC-E-BIFBADREG, Invalid register specified for builtin function
at line number 8 in file FREKE_1:[DANIEL.TEST]ASM.C;5

IA64 C compilers on other platforms have __getReg which support getting R8.

/Daniel
17 REPLIES 17
Ian Miller.
Honored Contributor

Re: Getting IA64 reg R8

what are you trying to achieve with getting the value of R0?
____________________
Purely Personal Opinion
John Reagan
Respected Contributor

Re: Getting IA64 reg R8

In general, asking for the contents of some general register would get you whatever the compiler had stuffed in there at that point. Certainly nothing of interest to a piece of C source code as it might change with each and every recompilation of the program.
Hoff
Honored Contributor

Re: Getting IA64 reg R8

Writing some non-portable code?

The register layout and usage is specific to the architecture, and also to the particular operating system and its calling standard.

With OpenVMS I64, Itanium register R8 is mapped to the traditional R0 usage of VAX and Alpha; the function return (condition) status processing is entirely transparent within the calling standard. R8 is an output register return from a function.

I'm sure you've seen it, but here's the register mapping:

http://h71000.www7.hp.com/DOC/82final/5601/5601pro_001.html#reg_map_table

Can't say I've had need to peek into the registers more than a handful of times -- can you provide some background on the problem you seeking to resolve here?

Dean McGorrill
Valued Contributor

Re: Getting IA64 reg R8

Hi Daniel,
I'm curious to, as what you are trying to
do with user code looking a register. In my
former life looking at system crashes I routinely went through registers mapping them to machine listings of code, but only
at the time of the dump! compiled code will
move stuff in and out of registers.
Robert Gezelter
Honored Contributor

Re: Getting IA64 reg R8

Daniel,

I will not repeat what has been said.

The only situation where R8 (R0 on Alpha/VAX) is defined is IMMEDIATELY FOLLOWING the return from a subroutine or function.

While in C, it is optional to capture the return code, it is straightforward to do, even from within the clause of an IF statement. For example:

if ((Result = function(f)) == 0)
{
/* Error code for Return Code of 0 */
}

Please take careful note of the parenthesis. This code assigns the return of the function to the variable Result AND THEN compares it to 0.

At any other time, the contents of R8 (R0) can change randomly at code generator will.

- Bob Gezelter, http://www.rlgsc.com

Re: Getting IA64 reg R8

One (simple) example... Seeing if free is OK.

free is void free(void *) but returns a value.
One cannot redeclare free if some C headers are included.

$ ty free3.c
#include
#include
#include
#include
#include
#include

static const char *errno_str(void)
{
int lerrno;
char *buf;

lerrno = errno;
errno = 0;
buf = strerror(lerrno);
if (errno) {
return "The strerror call failed";
}
return buf;
}

void main(void)
{
char *p;
int i;

p = malloc(10);
if (!p) {
puts("malloc failed");
return;
}
free((void *)(p+1));
i = asm("");
if (i) {
printf("free failed: %d, errno: %s", i, errno_str());
}
}
$
$ cc free3
$ link free3
$ run free3
free failed: -1, errno: bad block address
$

In this example, it is in reality sufficient to just look at errno though.

/Daniel

Re: Getting IA64 reg R8

The former was on Alpha, I would like to do the same on IA64.
Ian Miller.
Honored Contributor

Re: Getting IA64 reg R8

Is your use of free() just an example or is does this want you want to do?

You appear to be relying on the undocumented behaviour of the C library routine free where it returns a condition code even though it is declared as void (). Do you know that the free() in the CRTL on OpenVMS I64 does the same? As you said you can check errno.

____________________
Purely Personal Opinion

Re: Getting IA64 reg R8

Although I am interested in this example,
I am also interested in getting register contents in general.

The free behaviour is documented and does the same on IA64...
http://h71000.www7.hp.com/doc/83final/5763/5763pro_036.html#index_x_975
http://h71000.www7.hp.com/doc/83final/5763/OVMS_83_CRTL_REF.PDF
Robert Gezelter
Honored Contributor

Re: Getting IA64 reg R8

Daniel,

Thank you for the citations to the documentation set. Citations clarify the question tremendously.

In this case, the question "How do I get R8?" is, in reality, the question "How do I get the return code from a routine that is declared "void"?

The short answer is: You cannot. Unless of course, the routine is not actually implemented as "void". In this case, the documentation would seem to indicate that while the standard header definition for "free" is void free(); the actual implementation (at least on OpenVMS) has been to return an int (0 or -1).

I do not have the time at this instant to do the checks, but the solution is to redefine free as an int (or a long).

Hacks to get R8 will not get a reliable result.

- Bob Gezelter, http://www.rlgsc.com

Re: Getting IA64 reg R8

Hi Robert,

The question is still "How do I get R8?"
I think it should be possible with getReg and would like an explanation why it is not and/or another way.

I aware of what compilers can do and I am fairly good at IA64 assembly.

It is impossible to redeclare free, a C compiler will generate an error. You can ofcourse decide to not include any of the C standard headers and declare free yourself but that is not possible in many cases.

/Daniel
Robert Gezelter
Honored Contributor

Re: Getting IA64 reg R8

Daniel,

I do not have the citation at hand, but my recollection is that the return code (on Alpha generally R0 or F0; on IA64 actual R8) is not defined for a "void" procedure. Thus, as has been noted, the contents of the register are NOT DEFINED. Any state in R8 at return by a void function is undefined (in specification-ese). The translation is: Undefined means Undefined; do not experiment, the results may (and frequently do) vary unpredictably. [If you are interested in the history of that phrasing, my recollection is that the first recorded reference is in IBM's "System/360: Principles of Operation" from the early 1960's.]

In light of the comment that you cite from the documentation, perhaps somebody from Engineering can illuminate how to properly access the old behavior identified in the documentation.

My personal choice would be to alter the stdlib definition to "jacket" the "free" definition so that it can be overridden in advance. Another possibility is to define "free" as a macro invoking "ifree" after the invocation of stdlib.h, and then using the LINKER to substitute "free" for "ifree" at link time.

I would do the experiments to verify these, but I have to give priority to the several client projects that are on deadline today.

- Bob Gezelter, http://www.rlgsc.com
John Reagan
Respected Contributor
Solution

Re: Getting IA64 reg R8

getreg does not know how to return general register contents. We intentionally did not provide that ability. Even in the case you cite with free(), there is nothing that would prevent the compiler from reusing r8 between the return of free() and you invocation of getreg. You can try using the LIB$ calling standard routines to fill an ICB with various register values. It isn't cheap however.

John
Robert Gezelter
Honored Contributor

Re: Getting IA64 reg R8

John,

For consistency, what is the recommended method to access the historical functionality of "free" being declared as "int" not "void".

- Bob Gezelter, http://www.rlgsc.com
Dean McGorrill
Valued Contributor

Re: Getting IA64 reg R8

I suppose you could write your own free,
either make return a status or stick status
in a declared global cell. whatever the routine, the real work is done is exe$deallocate & exe$deapaged.
Fyi I routinely used the free
sysgen cells to read/write to running code where I'd tuck status/variables in
these cells and read/write using the sysgen utility.

SGN$GL_USERD1
SGN$GL_USERD2
SGN$GL_USER3
SGN$GL_USER4

Dean
John Reagan
Respected Contributor

Re: Getting IA64 reg R8

The other suggestion I've given is to declare decc$free directly and call it instead of free()

extern int decc$free(void *);

Robert Gezelter
Honored Contributor

Re: Getting IA64 reg R8

John,

So, I guess the recommendation would be to define a macro definition that referred all "free" references to decc$free, declared as:

extern int decc$free(void *);

e.g. (admittedly untested):

#define free(x) decc$free(x)

after the standard headers have already been included to preserve backwards compatibility for those programs that presume the historical (non-conforming) behavior.

- Bob Gezelter, http://www.rlgsc.com