[M3devel] m3_load/m3_store/bit_field_ref lose offset??

Jay jay.krell at cornell.edu
Sun Dec 14 10:20:13 CET 2008


Treelang doesn't look hopeful. It is more like a "real language", though incomplete, and less about "direct tree building".
I was hoping for something Lisp-like that mapped directly to the internal data structures.
For now, I'm tired/lame/impatient, and will just stick with the "* 2" patch.
Or maybe when we call relayout_decl, we can have a proper size.
Maybe loads of module globals should go through some more specific than m3_load, and we can track the maximum offset.

I'll try to write something reasonable to the gcc folks..
 
I could possibly write my own "treelang", but it doesn't seem worth the time currently, too much else to do.
 
 
 - Jay



From: jay.krell at cornell.edu
To: hosking at cs.purdue.edu
CC: m3devel at elegosoft.com
Subject: FW: [M3devel] m3_load/m3_store/bit_field_ref lose offset??
Date: Sun, 14 Dec 2008 08:40:05 +0000



(truncated and reedited)



Well, they are, definitely, but not with any fields, I think.
Like, we say there is a struct with size=align=maxalign, and then we access bit fields an offset from it.
If maxalign is large enough, no chance of the struct fitting in a register.

I meant, like, a struct where each module global is an actual declared/typed/sized field/member/component/whatever in the struct, not just "randomly" accessing way into and past the struct.
 
I'm delayed now for a day or so but I'll see if I can get a repro using "treelang".
Hopefully, going from just its name, it lets you build the exact trees that parse.c builds.
As well I should be able to use mips64/netbsd or mips64/linux. OpenBSD isn't supported
in current gcc without small patches (which cm3 applies).
And then ask the gcc folks (cc you/all?)
I can also try reproing with x86/AMD64/ppc lowering maxalign to 32 or 64.
 
 - Jay









From: hosking at cs.purdue.edu
To: jay.krell at cornell.edu
Date: Sun, 14 Dec 2008 17:23:06 +1100
CC: m3devel at elegosoft.com
Subject: Re: [M3devel] m3_load/m3_store/bit_field_ref lose offset??






I thought module globals *were* declared as a struct -- it's been a while...


On 14 Dec 2008, at 16:53, Jay wrote:


I tried getting C to error this way, and failed.
It looks like C uses COMPONENT_REF here, which will send it down different paths I didn't follow.
COMPONENT_REF makes sense for it and only somewhat sense for us.
That would involve declaring all of a module's globals a struct, which I don't believe we currently do but might be good. I think there's a basic disconnect in that in C, bitfields are always fields, never freestanding. Modula-3 rather violates that. Seems a little dangerous therefore to be using them this way?
 
In terms of the inefficient option in parse.c, that would maybe go away, as all the offseting would be handled by the next level down, like, implementation of fields?
Well..that is assuming the only use offset != 0 in m3_load is for accessing module globals. I don't know if that is true.
 
Maybe another option, should be easy to implement but might compile slowly, is to cons up a field decl right there in m3_load/store? That would lead to a lot of extra nodes -- per access instead of declared once. I can try that out.
 
 - Jay






From: jay.krell at cornell.edu
To: hosking at cs.purdue.edu
CC: m3devel at elegosoft.com
Subject: RE: [M3devel] m3_load/m3_store/bit_field_ref lose offset??
Date: Sat, 13 Dec 2008 18:03:08 +0000

I've just spent a few hours debugging this.
 
The problem is strongly related to the declaration that the global segment is of size BIGGEST_ALIGNMENT.
gcc decides they can fit in a register..so then it doesn't bother adding the offset to the address, something like that.
 
When things work, it goes here:
 op0 = adjust_address (op0, mode1, offset);  
in expr.c. When things don't work, that line is skipped and then shortly below that:
 
      if (mode1 != mode)
 return convert_to_mode (tmode, op0, unsignedp);
      return op0;  << 

On systems where BIGGEST_ALIGNMENT fits in a register, e.g. apparently MIPS, counter-e.g. apparently many others, but not clearly all others. This determines whether the mode of the segment is SImode (32bit integer), DImode (64bit integer) or BLKmode (larger than any machine type?). BLKmode works. It works on 32bit MIPS because between mode1 and mode, one of them is SImode, one is DImode. On x86/AMD64/PowerPC systems, I expect it is BLKmode, since biggest alignment is set very large -- 128. I don't know why it works for SPARC.
 
PERHAPS I can put together a C or treelang example and get more (gcc developers) eyes on it, but I doubt it.
 
The following hack works around it:
 
C:\dev2\cm3.2\m3-sys\m3cc\gcc\gcc\m3cg>cvs -z3 diff parse.c
Index: parse.c
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3cc/gcc/gcc/m3cg/parse.c,v
retrieving revision 1.77
diff -r1.77 parse.c
2865c2865
<     = m3_build_type (T_struct, BIGGEST_ALIGNMENT, BIGGEST_ALIGNMENT);
---
>     = m3_build_type (T_struct, BIGGEST_ALIGNMENT * 2, BIGGEST_ALIGNMENT);
 
The repro is very easy.
Just add this to m3core:
 
MODULE Main2 EXPORTS Main;
IMPORT RTIO;
VAR a := "a";
BEGIN
  RTIO.PutText(a);
END Main2.

The load of a will be from MM_Main2 offset 0, instead of 104 or thereabouts.
 
I'll commit this shortly.
 
 - Jay








From: jay.krell at cornell.edu
To: hosking at cs.purdue.edu
Date: Thu, 13 Nov 2008 00:04:32 +0000
CC: m3devel at elegosoft.com
Subject: Re: [M3devel] m3_load/m3_store/bit_field_ref lose offset??

> Jay, do you have access to an AMD64_DARWIN box?
 
No, sorry, I don't yet and not sure when I will.
Unless it is easy enough to run on non-Apple hardware.
I'll have to debug it (m3cg) then.
 
 - Jay











CC: m3devel at elegosoft.com
From: hosking at cs.purdue.edu
To: jay.krell at cornell.edu
Subject: Re: [M3devel] m3_load/m3_store/bit_field_ref lose offset??
Date: Wed, 12 Nov 2008 20:46:53 +0000

Jay, do you have access to an AMD64_DARWIN box?   I did get things working on that 64-bit platform.   Or is it an endianness issue you are dealing with.  In any case, I will not have a lot of bandwidth for doing much in the way of tackling this unless it becomes critical path for me soon.








Antony Hosking | Associate Professor | Computer Science | Purdue University
305 N. University Street | West Lafayette | IN 47907 | USA
Office +1 765 494 6001 | Mobile +1 765 427 5484





On 12 Nov 2008, at 07:57, Jay wrote:


Target.Little_endian is used to drive some target-specificity in the IR.
   I guess, after all, that is why you have to specify it.
 
The IR for RTLinker.m3 is identical for MIPS64_OPENBSD and SPARC64_SOLARIS, once I set them both to unaligned_procedures, which they both need. (Tangent, I ran m3cgcat on the .ms file a few times instead of the .mc file; that makes it crash.)
 
I can't claim SPARC64_SOLARIS is any paragon of working and correct though, by far.
I should also be able to compare with SPARC64_OPENBSD, I forgot about that, and didn't have an m3cg.
I only ran SPARC64_SOLARIS far enough to discover it needed unaligned procedures.
I think I should fork linux-common and solaris-common off of the minimal 29k openbsd-common, rather than worry about all the stuff in solaris-2-x and linux-libc, over 100k each. Then SPARC64_SOLARIS could/would be in better shape probably.
 
MIPS64_OPENBSD cm3 gets further with unaligned_procedures, along with the parse.c fix -- it gets to a bus error in RunMainBody.
Again an alignment problem, though I think maybe memory memory trashing.
The fault occurs here:
 
    desc_offset := init_depth * ADRSIZE (InitDesc);

      desc := init_stack + desc_offset;
      init_depth := desc.low_link; << 

  InitDesc = RECORD
    module   : RT0.ModulePtr;
    low_link : INTEGER;
  END;

desc_offset appears to not be a multiple of 4.
 
I will look into that.
 
Long story short -- consider again the parse.c change?
I admit I still haven't debugged it (or rather, the code that consumes the data produced by it).
 
 - Jay







From: jay.krell at cornell.edu
To: hosking at cs.purdue.edu
CC: m3devel at elegosoft.com
Subject: RE: [M3devel] m3_load/m3_store/bit_field_ref lose offset??
Date: Sun, 9 Nov 2008 11:10:54 +0000

I agree. I am suspicious too. I will investigate more. Thanks.
 
 - Jay








From: hosking at cs.purdue.edu
To: jay.krell at cornell.edu
Date: Sun, 9 Nov 2008 10:01:58 +0000
CC: m3devel at elegosoft.com
Subject: Re: [M3devel] m3_load/m3_store/bit_field_ref lose offset??




Aren't the integer values supposed to be written endian-independently in the IR?  I am suspicious about these differences.





On 9 Nov 2008, at 01:25, Jay wrote:


Thanks for the tip/direction.
 
Uncertain -- m3cgcat between AMD64_LINUX and MIPS64_OPENBSD are "the same" but for two systematic diffs:
 
 - AMD64_LINUX has a bunch of added calls to check_nil.
   This is a "bug" in it, inoptimal but ok code, because "first readable address" is 0. It should probably be 4k. I should write a program that iterates starting at 0 to find the value.
  (or better yet, cm3 should have a -configure option that does this? -- for configuration values for which there is a safe default; in general, imho, the targets should be auto configured via C, assuming there is a native development environment available).
 
 - some integers are different (again, systematically) 
 
AMD64_LINUX:
 init_int  656 13 Int.64
 init_chars  664 "    typecode "
 init_int  680 2 Int.64
 init_var  688 v.1 0
 init_int  696 13 Int.64
 init_chars  704 "    typeid   "
 init_int  720 2 Int.64
 init_var  728 v.1 0
 init_int  736 13 Int.64
 init_chars  744 "RunMainBody: "
 init_int  760 2 Int.64
 init_var  768 v.1 0
 init_int  776 19 Int.64
 init_chars  784 "RunMainBody: exec: "
 init_int  808 2 Int.64
 init_var  816 v.1 0
 init_int  824 17 Int.64
 init_chars  832 "ExpandInitStack: "

MIPS64_OPENBSD:
 
 init_chars  664 "    typecode "
 init_int  680 8796093022208 Int.64
 init_var  688 v.1 0
 init_int  696 13 Int.64
 init_chars  704 "    typeid   "
 init_int  720 8796093022208 Int.64
 init_var  728 v.1 0
 init_int  736 13 Int.64
 init_chars  744 "RunMainBody: "
 init_int  760 8796093022208 Int.64
 init_var  768 v.1 0
 init_int  776 19 Int.64
 init_chars  784 "RunMainBody: exec: "
 init_int  808 8796093022208 Int.64
 init_var  816 v.1 0

This 8796093022208 is 80000000000 aka 0000_0800_0000_0000, where little endian has 2.
 
I don't know what these numbers represent.
I should look at other systems -- preferably a working 64 bit big endian system, if there are any.
 
Could be flags/type with text literals?
 
(Btw, I always leave the TextLiteral.i3 change on my system, lowering the maximum literal length to around 4gig even on 64 bit targets, so 32 bit can bootstrap 64 bit...need to fix the compiler here to do target arithmetic instead of host arithmetic...)
 
Thanks,
 - Jay






From: hosking at cs.purdue.edu
To: jay.krell at cornell.edu
Date: Sat, 8 Nov 2008 22:55:54 +0000
CC: m3devel at elegosoft.com
Subject: Re: [M3devel] m3_load/m3_store/bit_field_ref lose offset??

Have you checked to make sure that the pre-gcc IR makes sense?  Does it see these values as 32-bit or 64-bit?  The reason I ask is that there may be something wrong in your m3middle target specs that cause bad IR.  Once we know the IR looks right then we can try and fix the problem.





Antony Hosking | Associate Professor | Computer Science | Purdue University
305 N. University Street | West Lafayette | IN 47907 | USA
Office +1 765 494 6001 | Mobile +1 765 427 5484





On 8 Nov 2008, at 15:45, Jay wrote:



truncated as usual...along with losing a lot of whitespace..
Let's see...


Tony, how about switching these #if's?
I explain some of why below.

static void
m3_store (tree v, int o, tree src_t, m3_type src_T, tree dst_t, m3_type dst_T)
{
 tree val;
#if 0
 if (o != 0 || TREE_TYPE (v) != dst_t) {
   v = m3_build3 (BIT_FIELD_REF, dst_t, v, TYPE_SIZE (dst_t),
    bitsize_int (o));
 }
#else
 /* failsafe, but inefficient */
 if (o != 0 || TREE_TYPE (v) != dst_t) {
   v = m3_build1 (ADDR_EXPR, t_addr, v);
   v = m3_build2 (PLUS_EXPR, t_addr, v, size_int (o / BITS_PER_UNIT));
   v = m3_build1 (INDIRECT_REF, dst_t,
    m3_cast (build_pointer_type (dst_t), v));
 }
#endif
 TREE_THIS_VOLATILE (v) = 1; /* force this to avoid aliasing problems */
 val = m3_cast (src_t, EXPR_REF (-1));
 if (src_T != dst_T) {
   val = m3_build1 (CONVERT_EXPR, dst_t, val);
 }
 add_stmt (build2 (MODIFY_EXPR, dst_t, v, val));
 EXPR_POP ();
}
m3_load (tree v, int o, tree src_t, m3_type src_T, tree dst_t, m3_type dst_T)
{
#if 0
 if (o != 0 || TREE_TYPE (v) != src_t) {
   v = m3_build3 (BIT_FIELD_REF, src_t, v, TYPE_SIZE (src_t),
    bitsize_int (o));
 }
#else
 /* failsafe, but inefficient */
 if (o != 0 || TREE_TYPE (v) != src_t) {
   v = m3_build1 (ADDR_EXPR, t_addr, v);
   v = m3_build2 (PLUS_EXPR, t_addr, v, size_int (o / BITS_PER_UNIT));
   v = m3_build1 (INDIRECT_REF, src_t,
    m3_cast (build_pointer_type (src_t), v));
 }
#endif
 TREE_THIS_VOLATILE (v) = 1; /* force this to avoid aliasing problems */
 if (src_T != dst_T) {
   v = m3_build1 (CONVERT_EXPR, dst_t, v);
 }
 EXPR_PUSH (v);
}

I'm working on MIPS64_OPENBSD (OpenBSD on an SGI O2).
In an early version it seems that many loads/stores of global variables is wrong.
The "first" code affected is RTLinker_ExpandModuleTable.

PROCEDURE ExpandModuleTable () =
 CONST InitialTableSize = 500;
 VAR new_mods: ADDRESS;  n_bytes: INTEGER;
 BEGIN
   IF (modules = NIL) THEN
     (* first time... *)
     max_modules := InitialTableSize;
     modules := Cstdlib.malloc (InitialTableSize * BYTESIZE (RT0.ModulePtr));
     IF (modules = NIL) THEN Cstdlib.abort (); END;
   ELSE
     n_bytes := max_modules * BYTESIZE (RT0.ModulePtr);
     new_mods := Cstdlib.malloc (n_bytes + n_bytes);
     IF (new_mods = NIL) THEN Cstdlib.abort (); END;
     EVAL Cstring.memcpy (new_mods, modules, n_bytes);
     Cstdlib.free (modules);
     modules := new_mods;
     INC (max_modules, max_modules);
   END;
 END ExpandModuleTable;

It should read back modules as NIL.
What happens is it reads back modules as not NIL,
and then max_modules should also be zero, but is "large", leading to malloc to fail,
and abort called.

The output of cm3cg -y is reasonable.
It indicates offset loads.

What is incorrect is that in many loads and stores, but not all, the
offsets are lost.

(923) begin_procedure
 procedure RTLinker__ExpandModuleTable
RTLinker__ExpandModuleTable(924) set_source_line
 source line  208
(925) load_nil
(926) store
 store (M3_AJWxb1_new_mods) offset 0x0 src_t 0xb dst_t 0xb
(927) set_source_line
 source line  207
(928) set_source_line
 source line  210
(929) load_nil
(930) load
 m3cg_load (MM_RTLinker): offset 0x440, convert 0xb -> 0xb

Here is the incorrect code:

.globl RTLinker__ExpandModuleTable
.stabd 46,0,0
.stabn 68,0,206,.LM108
.LM108:
.LFBB8:
.set nomips16
.ent RTLinker__ExpandModuleTable
RTLinker__ExpandModuleTable:
.frame $fp,64,$31  # vars= 32, regs= 3/0, args= 0, gp= 0
.mask 0xd0000000,-8
.fmask 0x00000000,0
daddiu $sp,$sp,-64
sd $31,56($sp)
sd $fp,48($sp)
sd $28,40($sp)
move $fp,$sp
lui $28,%hi(%neg(%gp_rel(RTLinker__ExpandModuleTable)))
daddu $28,$28,$25
daddiu $28,$28,%lo(%neg(%gp_rel(RTLinker__ExpandModuleTable)))
.LBB9:
.stabn 68,0,208,.LM109
.LM109:
sd $0,16($fp)
.stabn 68,0,210,.LM110
.LM110:
dla $2,MM_RTLinker
ld $2,0($2)      << WRONG
bne $2,$0,.L61
.stabn 68,0,212,.LM111
.LM111:
dla $3,MM_RTLinker
ld $2,128($3)
andi $2,$2,0x0
ori $2,$2,0x1f4
sd $2,128($3)
.stabn 68,0,213,.LM112
.LM112:
li $4,4000   # 0xfa0
jal malloc
sd $2,0($fp)
ld $4,0($fp)
dla $3,MM_RTLinker
ld $2,136($3)
andi $2,$2,0x0
or $2,$4,$2
sd $2,136($3)     << OK, offset seems low, but it agrees with elsewhere 
.stabn 68,0,214,.LM113
.LM113:
dla $2,MM_RTLinker
ld $2,0($2)       << WRONG 
bne $2,$0,.L65
jal abort
b .L65
.L61:
.stabn 68,0,216,.LM114
.LM114:
dla $2,MM_RTLinker
ld $2,0($2)        << WRONG 
dsll $2,$2,3
sd $2,8($fp)
.stabn 68,0,217,.LM115
.LM115:
ld $3,8($fp)
ld $2,8($fp)
daddu $2,$3,$2
move $4,$2
jal malloc
sd $2,0($fp)
ld $2,0($fp)
sd $2,16($fp)
.stabn 68,0,218,.LM116
.LM116:
ld $2,16($fp)
bne $2,$0,.L64
jal abort
.L64:
.stabn 68,0,219,.LM117
.LM117:
ld $4,16($fp)
dla $2,MM_RTLinker
ld $2,0($2)          << WRONG
ld $3,8($fp)
move $5,$2
move $6,$3
jal memcpy
sd $2,0($fp)
.stabn 68,0,220,.LM118
.LM118:
dla $2,MM_RTLinker
ld $2,0($2)           << WRONG
move $4,$2
jal free
.stabn 68,0,221,.LM119
.LM119:
ld $4,16($fp)
dla $3,MM_RTLinker
ld $2,136($3)         << OK
andi $2,$2,0x0
or $2,$4,$2
sd $2,136($3)         << OK 
.stabn 68,0,222,.LM120
.LM120:
dla $2,MM_RTLinker
ld $3,0($2)           << WRONG
dla $2,MM_RTLinker
ld $2,0($2)           << WRONG
daddu $4,$3,$2
dla $3,MM_RTLinker
ld $2,128($3)         << OK
andi $2,$2,0x0
or $2,$2,$4
sd $2,128($3)         << OK
.L65:
.LBE9:
.stabn 68,0,224,.LM121
.LM121:
move $sp,$fp
ld $31,56($sp)
ld $fp,48($sp)
ld $28,40($sp)
daddiu $sp,$sp,64
j $31
.end RTLinker__ExpandModuleTable

Here is corrected code:

RTLinker__ExpandModuleTable:
.frame $fp,64,$31  # vars= 32, regs= 3/0, args= 0, gp= 0
.mask 0xd0000000,-8
.fmask 0x00000000,0
daddiu $sp,$sp,-64
sd $31,56($sp)
sd $fp,48($sp)
sd $28,40($sp)
move $fp,$sp
lui $28,%hi(%neg(%gp_rel(RTLinker__ExpandModuleTable)))
daddu $28,$28,$25
daddiu $28,$28,%lo(%neg(%gp_rel(RTLinker__ExpandModuleTable)))
.LBB9:
.stabn 68,0,208,.LM109
.LM109:
sd $0,16($fp)
.stabn 68,0,210,.LM110
.LM110:
dla $2,MM_RTLinker
daddiu $2,$2,136     << CORRECT (offset seems low, but at least it isn't zero) 
ld $2,0($2)
bne $2,$0,.L61
.stabn 68,0,212,.LM111
.LM111:
dla $2,MM_RTLinker
daddiu $3,$2,128     << CORRECT 
li $2,500   # 0x1f4
sd $2,0($3)
.stabn 68,0,213,.LM112
.LM112:
li $4,4000   # 0xfa0
jal malloc
sd $2,0($fp)
dla $2,MM_RTLinker
daddiu $3,$2,136      << CORRECT 
ld $2,0($fp)
sd $2,0($3)
.stabn 68,0,214,.LM113
.LM113:
dla $2,MM_RTLinker
daddiu $2,$2,136      << CORRECT 
ld $2,0($2)
bne $2,$0,.L65
jal abort
b .L65
.L61:

I still dump core with this change, but I get much further.
I have not tested this change at all otherwise -- i.e. on working platforms.

I have not debugged through the gcc/m3cg code to see why
the offsets are only sometimes lost, or why other platforms
have no problem. Is MIPS's "global pointer" unusual these days?
I know SPARC has similar, and all the non-x86, non-AMD64 NT platforms
had similar, but that's essentially nothing now (I'm not counting IA64).
I know Linux has PLT (procedure linkage table) and GOT (global offset table).
Same thing?
I haven't looked much at other MIPS ports yet.

http://modula3.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-sys/m3cc/gcc/gcc/m3cg/parse.c.diff?r1=1.7;r2=1.8

is what made it look about like it does -- in particularing using BIT_FIELD_REF.

1.7:

static void m3_load (v, o, src_t, src_T, dest_t, dest_T) /* GCC32OK */
    tree v;
    int o;
    tree src_t, dest_t;
    m3_type src_T, dest_T;
{
 if (o == 0 && TREE_TYPE (v) == src_t) {
   EXPR_PUSH (v);
 } else {
   tree adr = m3_build1 (ADDR_EXPR, t_addr, v);
   if (o != 0) {
     adr = m3_build2 (PLUS_EXPR, t_addr, adr, size_int (o / BITS_PER_UNIT));
   }
   EXPR_PUSH (m3_build1 (INDIRECT_REF, src_t,
                         m3_cast (build_pointer_type (src_t), adr)));
 }
#if 1
 if (src_T != dest_T) {
   EXPR_REF (-1) = m3_build1 (CONVERT_EXPR, dest_t, EXPR_REF (-1));
 }
 if (debug_vars) {
   const char *name = "noname";
   if (v != 0 && DECL_NAME(v) != 0) {
     name = IDENTIFIER_POINTER(DECL_NAME(v));
   }
   fprintf(stderr, "  m3_load (%s): offset %d, convert %d -> %d\n", name,
           o, src_T, dest_T);
 }
#else
 if (src_T != dest_T) {
   if (IS_INTEGER_TYPE(dest_T) && dest_t != t_int) {
     EXPR_REF (-1) = m3_build1 (CONVERT_EXPR, t_int, EXPR_REF (-1));
   } else if (IS_WORD_TYPE(dest_T) && dest_t != t_word) {
     EXPR_REF (-1) = m3_build1 (CONVERT_EXPR, t_word, EXPR_REF (-1));
   } else if (IS_INTEGER_TYPE(dest_T) || IS_WORD_TYPE(dest_T)) {
     /* okay */
   } else {
     fatal_error("m3load: cannot convert types: src_t %d dest_t %d\n",
                 src_T, dest_T);
   }
 }
#endif
}
static void
m3_store (v, o, src_t, dest_t)  /* GCC32OK */
    tree v;
    int o;
    tree src_t, dest_t;
{
 tree lhs, rhs;
 if (TREE_TYPE (EXPR_REF (-1)) == src_t) {
   rhs = EXPR_REF (-1);
 } else {
   rhs = m3_cast (src_t, EXPR_REF (-1));
 }
 if (o == 0 && TREE_TYPE (v) == dest_t) {
   lhs = v;
 } else {
   tree f = make_node (FIELD_DECL);
   TREE_TYPE (f) = dest_t;
   DECL_ALIGN (f) = TYPE_ALIGN (dest_t);
   DECL_SIZE (f) = TYPE_SIZE (dest_t);
   DECL_MODE (f) = TYPE_MODE (dest_t);
   DECL_FIELD_OFFSET (f) = size_int (o / BITS_PER_UNIT);
   DECL_FIELD_BIT_OFFSET (f) = bitsize_int (o % BITS_PER_UNIT);
   DECL_FIELD_CONTEXT (f) = TREE_TYPE (v);
   lhs = m3_build2 (COMPONENT_REF, dest_t, v, f);
 }
#if 1
   expand_assignment (lhs, m3_build1 (CONVERT_EXPR, dest_t, rhs), 0, 0);
#else
 if (dest_t ==  NULL) {
   expand_assignment (lhs, rhs, 0, 0);
 } else {
   expand_assignment (lhs, m3_build1 (CONVERT_EXPR, dest_t, rhs), 0, 0);
 }
#endif
 EXPR_POP ();
}

1.8:
static void
m3_load (tree v, int o,
 tree src_t, m3_type src_T,
 tree dst_t, m3_type dst_T) /* GCC32OK */
{
 if (o == 0 && TREE_TYPE (v) == src_t) {
   EXPR_PUSH (v);
 } else {
   EXPR_PUSH (m3_build3 (BIT_FIELD_REF, src_t, v, TYPE_SIZE (src_t),
    bitsize_int (o)));
 }
 if (src_T != dst_T) {
   EXPR_REF (-1) = m3_build1 (CONVERT_EXPR, dst_t, EXPR_REF (-1));
 }
 if (option_vars_trace) {
   const char *name = "noname";
   if (v != 0 && DECL_NAME(v) != 0) {
     name = IDENTIFIER_POINTER(DECL_NAME(v));
   }
   fprintf(stderr, "  m3_load (%s): offset %d, convert %d -> %d\n", name,
    o, src_T, dst_T);
 }
}
static void
m3_store (tree v, int o, tree src_t, tree dst_t)  /* GCC32OK */
{
 tree lhs, rhs;
 if (TREE_TYPE (EXPR_REF (-1)) == src_t) {
   rhs = EXPR_REF (-1);
 } else {
   rhs = m3_cast (src_t, EXPR_REF (-1));
 }
 if (o == 0 && TREE_TYPE (v) == dst_t) {
   lhs = v;
 } else {
   lhs = m3_build3 (BIT_FIELD_REF, dst_t, v, TYPE_SIZE (dst_t),
      bitsize_int (o));
 }
 if (src_t != dst_t) {
   rhs = m3_build1 (CONVERT_EXPR, dst_t, rhs);
 }
 expand_assignment (lhs, rhs, 0, 0);
 EXPR_POP ();
}

- Jay




More information about the M3devel mailing list