Sorry, got confused by the subject: it's not code that's being
misplaced, but data.  I agree -mmemory-model=medium is inappropriate
in this case.

The short answer is: if you have something that works for you, use it.

There seems to be a bunch of things not working right here, among them
that I can't replicate the assembly you get from the code you
provided.  That it works with -mmemory-model=large is what I'd expect.
 If you apply the patch below, you should be able to use -md20 -msr20,
and I think it would work with that too.  However, the bulk of the
code size increase you saw with -mmemory-model=large is due to -md20.

Which means you need to use mixed memory-model programming to solve
this. As I noted at
https://sourceforge.net/apps/mediawiki/mspgcc/index.php?title=Gcc47:20-Bit_Design#mixedmode
this does not work as I had hoped and intended.  Some of what you see
seems to be due to those core assumptions in GCC that the MSP430
architecture violates: mspgcc thought the address of the pointer was
20-bit when it got loaded into a register, but when it stored the
value back out to a 32-bit integer it used the pattern for a 16-bit
sign extension.

In fact, I can't replicate the compiled code you got: all my attempts
show it treating those addresses as 16 bits.  Could you please open a
tracker ticket for this at
https://sourceforge.net/tracker/?group_id=42303&atid=432701, with the
example you just sent and the compiler flags you used?

Since I can't replicate what you see, I can't judge whether there are
hidden problems.

Also consider using uint20_t when you need to store a 20-bit pointer
into something that's 32-bits when it's in memory.  It should be more
efficient.

For what it's worth, what I think you're trying to do should be
expressable this way:

#include <stdlib.h>

const char __attribute__((__far__)) lut[32000] = { 1, 2, 3, 4, 5 };

int
copylut (char * dst,
         size_t len,
         unsigned int index)
{
  size_t i;
  const char * __attribute__((__a20__)) src = lut;
  src += index;
  for (i = 0; i < len; ++i) {
    dst[i] = src[i];
  }
  return len;
}

It'd be nice if you could use memcpy, but you can't because passing it
two different types of pointer would really cause trouble.  This
should work without memory model flags.  It doesn't, and that's one of
the things I'll look into when I get back to mspgcc, but that won't be
for a couple weeks.

Also see 
https://sourceforge.net/tracker/?func=detail&aid=3563513&group_id=42303&atid=432701
which is another way you might try to do it, which also doesn't work
but for a different reason.

Here's the patch that should eliminate the problems that result
because there is no pre-defined memory model for -md20 -msr20.  I
can't promise it wouldn't break something else.  The workaround of
having an explicit section is a reasonable alternative, though you
should still keep the __far__ attribute on there since that has other
side effects that you'd want (like eliminating the need for __d20__).

diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index c83cb5a..9147101 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -2970,8 +2970,10 @@ secregion_for_decl (const_tree decl)
       && FUNCTION_DECL == TREE_CODE (decl)
       && NULL_TREE != lookup_attribute (S_interrupt, DECL_ATTRIBUTES (decl)))
     return MSP430_SECTION_REGION_NEAR;
+#if 0
   if (MSP430_MEMORY_MODEL_NONE == msp430_memory_model)
     return MSP430_SECTION_REGION_DEFAULT;
+#endif
   if (VAR_OR_FUNCTION_DECL_P (decl))
     {
       bool has_near_attr;

Peter

On Thu, Aug 30, 2012 at 3:32 PM, Shalabh Jain <shalabh.j...@gmail.com> wrote:
> Hi Peter
>
> Thanks for the advice. That seems to solve the problem. However, I have a
> few more questions and suggestions
>
> On Wed, Aug 29, 2012 at 3:19 AM, Peter Bigot <big...@acm.org> wrote:
>
>> Use '-mmemory-model=large' instead of the underlying flags and your
>> code should work.  (In fact, use -mmemory-model=medium unless you need
>> code in far memory: due to limitations in gcc that I've mentioned
>> before certain optimizations get disabled when sizeof(void*) !=
>> sizeof((*)(void)), which only holds when -md20 != -ma20.)
>>
>> The memory model large does the correct placement and code generation.
> However, since it implicitly converts all the instructions to 20 bit
> variant, which causes significant overhead. I did some experiments and I
> see almost 15% increase in code size and 50% increase in runtime. This is
> quite critical for our application.
>
> Secondly, memory-model medium errors out since it doesn't include -md20
> flag. So that option though may reduce overhead, doesn't work!
>
> My task requirements are simple. I need to put multiple LUTs in the far
> memory (because of the size) and I had just one function accessing it to
> copy the data to temporary local variables. The overhead seems way too much
> for that.
>
> Here's what I did to get it to work and the problems encountered.
>
> It seems that only the placement of the code is a problem in the memory. I
> can manually change that by adding a section(".far.rodata") attribute along
> with the __d20__ attribute. This places the code correctly and the pointer
> is correctly made taken to be 20 bits, even without any memory related
> compilation flags. I can then use a small assembly routine (similar to the
> btstack flash memory access function) to copy the data. However, I need the
> pointers to all my LUTs accessible in a single pointer array. Here are the
> problems associated with this. I'm not sure if these are bugs/enhancement
> requests
> 1. The pointer array would need the underlying type __a20__. The compiler
> errors out saying that __a20__ cannot be applied to *[10] type element.
> 2. I tried to make the array as uint32_t and keeping the addresses in the
> array. From the assembly code generated, it seems that the compiler retains
> the 20 bits only for the first move and discards it in the later stages.
> This seems like a bug.  My workaround was to write assembly code for this
> operation as well. Here's a small example of where the error comes.
>
> A program of type
> const char abc[5] __attribute__((__d20__, section(".far.rodata"))) = {1, 2,
> 3, 4, 5};
> const char bcd[5] __attribute__((__d20__, section(".far.rodata"))) = {1, 2,
> 3, 4, 5};
> uint32_t add[2];
> void main() {
>     add[0] = abc;
>     add[1] = bcd;
> }
>
> Gets converted into the assembly as (only the first part)
>     5c3e:       3e 40 00 1c     mov     #7168,  r14     ;#0x1c00
>     5c42:       8f 01 05 00     mova    #0x10005,r15
>     5c46:       8e 4f 00 00     mov     r15,    0(r14)  ;0x0000(r14)
> // ok till here
>     5c4a:       8f 10           swpb
> r15                                          //this kills the higher order
> bits
>     5c4c:       8f 11           sxt     r15
>     5c4e:       8f 10           swpb    r15
>     5c50:       8f 11           sxt     r15
>     5c52:       8e 4f 02 00     mov     r15,    2(r14)  ;0x0002(r14)
>
> I can workaround this by simply using
> __asm__ __volatile__ ("movx.a %0, %1\n"::"i"(abc), "m"(add[0]));
>
> This seems like something the compiler should be able to do!
>
> I would like to just verify with you if you see any problems with the way
> these things have been handled. The code seems to work fine for now, but I
> cannot guarantee correctness.
>
> Thanks for all your help
>
> Shalabh
>
>
>
>
>> As it turns out, though my intent was that compilation would be
>> determined solely by the -mX20 flags, the text of
>>
>>
>> https://sourceforge.net/apps/mediawiki/mspgcc/index.php?title=Gcc47:20-Bit_Design#memmodel
>>
>> is partially correct in its statement that if you leave the default
>> memory model at "none", everything is assumed to be 16-bit.  There is
>> exactly one use of the -mmemory-model flag in mspgcc, and what that
>> use does is force data into the default region.
>>
>> I'm not sure yet whether this is going to be a bug or a documentation
>> change.  It's now recorded as 3562647 for future review.
>>
>> Peter
>>
>>
>> On Tue, Aug 28, 2012 at 11:33 PM, Shalabh Jain <shalabh.j...@gmail.com>
>> wrote:
>> > Hi,
>> >
>> > I recently installed the 20120716 release (following the instructions in
>> > the readme and wiki). The installation seems fine as I can compile and
>> > correctly run the my code from v4.6.
>> >
>> > My chip is msp430f5438a on the experimenter board.
>> >
>> > I would like to put a lookup table in the far memory region. I was
>> testing
>> > some simple code using the __far__ attribute, but the code seems to be
>> > getting placed in the near region. I'm sure I'm missing something silly.
>> > Can somebody please help. (Note: The code is not mean to produce anything
>> > meaningful. I simply need to see if the memory assignment is happening
>> > correctly, for which I am using msp430-objdump
>> >
>> > My sample code
>> >
>> > #include <stdio.h>
>> > #include "sj.h"
>> > /* contains an initialized array declared as
>> > const char kuttest[30000]  __attribute__((__far__)) =
>> > { 1, \
>> > 2, \
>> > 2, \
>> > 2, \
>> > 2, \
>> > 2, \
>> > ...
>> > };
>> >
>> > int putchar(int c) {return 0;}
>> >
>> > void main() {
>> >     int res;
>> >     const char * __attribute__((__a20__)) abc = kuttest;
>> >     for(res = 0; res < 10; res++)
>> >     printf("%x abc", *(abc+res));
>> > }
>> >
>> > I am compiling this will the most conservative options
>> > msp430-gcc-4.7.0 -mmcu=msp430f5438a -md20 -msr20 -mdata-region=far -mc20
>> > -mcode-region=far fardata.c  -Wall -o fardata
>> >
>> > The code compiles fine (with the warning about main return type not being
>> > int).
>> > The objectdump shows me
>> >
>> > Disassembly of section .rodata:
>> >
>> > 000066d6 <kuttest>:
>> >     66d6:       01 02           mova    #4,     r1      ;r2 As==10
>> >     66d8:       02 02           mova    #4,     r2      ;r2 As==10
>> >     66da:       02 02           mova    #4,     r2      ;r2 As==10
>> >     66dc:       02 02           mova    #4,     r2      ;r2 As==10
>> >     66de:       02 02           mova    #4,     r2      ;r2 As==10
>> >     66e0:       02 02           mova    #4,     r2      ;r2 As==10
>> >     66e2:       02 02           mova    #4,     r2      ;r2 As==10
>> >     66e4:       02 02           mova    #4,     r2      ;r2 As==10
>> >
>> > The variable is not in the far address space.
>> >
>> > Any help is appreciated.
>> >
>> > Thanks a lot
>> >
>> > Shalabh
>> >
>> >
>> ------------------------------------------------------------------------------
>> > Live Security Virtual Conference
>> > Exclusive live event will cover all the ways today's security and
>> > threat landscape has changed and how IT managers can respond. Discussions
>> > will include endpoint security, mobile security and the latest in malware
>> > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
>> > _______________________________________________
>> > Mspgcc-users mailing list
>> > Mspgcc-users@lists.sourceforge.net
>> > https://lists.sourceforge.net/lists/listinfo/mspgcc-users
>> >
>>
>
> ------------------------------------------------------------------------------
> Live Security Virtual Conference
> Exclusive live event will cover all the ways today's security and
> threat landscape has changed and how IT managers can respond. Discussions
> will include endpoint security, mobile security and the latest in malware
> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
> _______________________________________________
> Mspgcc-users mailing list
> Mspgcc-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mspgcc-users
>

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

Reply via email to