[comp.sys.m68k] cast

rl@cbnewsl.att.com (roger.h.levy) (08/08/90)

We have a substantial amount of C code originally targeted to a 68008
system and now being ported to a 68000 system.  In the past, we have
casted character pointers to integer pointers in some situations and
then dereferenced the pointer.  Although this works OK with a 68008,
it will result in a bus error on our 68000 target if the address of
the data is odd.  Since we need to correct our code, I was wondering
whether a tool exists that can identify instances of such statements.
BTW, I checked my K&R and noted the warning about possible addressing
errors as a result of this practice.  We realize the error of our
ways so no further scolding is necessary.

Roger Levy
...!rl@groucho.ATT.COM

mcmahan@netcom.UUCP (Dave Mc Mahan) (08/08/90)

 In a previous article, rl@cbnewsl.att.com (roger.h.levy) writes:
>We have a substantial amount of C code originally targeted to a 68008
>system and now being ported to a 68000 system.  In the past, we have
>casted character pointers to integer pointers in some situations and
>then dereferenced the pointer.  Although this works OK with a 68008,
>it will result in a bus error on our 68000 target if the address of
>the data is odd.  Since we need to correct our code, I was wondering
>whether a tool exists that can identify instances of such statements.
>BTW, I checked my K&R and noted the warning about possible addressing
>errors as a result of this practice.  We realize the error of our
>ways so no further scolding is necessary.

There are a couple of ways to get around this.  The first is tedious and
consumes lots of memory (2 bytes for every character declared) but is good
to do in the long run to solve portability problems.

Go through each function and change all the explicit declarations to
typedef's.  Thus, you would do something like:

typedef		char	CHAR;
typedef		int	INT;
typedef		unsigned int	UINT;
typedef		unsigned long	ULONG;

Make sure you also do this in the casts.  This allows you to set the size
of each variable type on your machine.  For your case, you would compile the
whole mess with the stuff above to make sure it still provides the same type
of output, and then go in and change all the CHAR typedefs to:

typedef		int	CHAR;

This will make all your character arrays at least 16 bits wide and force them
all to even boundaries.  Note that this may get a little hairy when you try
to access hardware explicitly.

The other way to get rid of this problem is to check out your compiler to see
if it has a way to force all your odd addressed variables to even addresses.
This might be as a switch to go from the 68008 to the 68000 or a -EVEN switch
that causes all variable bases to begin on even addresses.  I don't know what
compiler you have, so I guess you are on your own.

I think the second method probably won't work too well in your case.  It
appears that you have been doing nasty-NoNo things like setting integer
pointers into the middle of character strings (like trying to parse stuff
as it comes in a comm port and bytes 3 and 4 contain an integer value).  The
compiler likes this stuff as much as any other and it is not technically a
syntax error, so I doubt you will find a tool (like lint) that would catch
such a thing.  It would be very difficult and a smart tool indeed, since you
could concievably set a byte pointer to an even address (which is ok),
increment it twice and use it as an int pointer (which is ok), then increment
it 5 times and use it as an int pointer (which is not ok).  How can a tool
figure out such a mess?  It would have to go through all permutations to
find what you mean.

Another alternative comes to mind.  You can trap the exception vector that
occurs from this type of addressing, decode the instruction via a software
exception handler, and do 'the right thing'.  This might work theoretically,
but good luck making it go in the real world!  I assume you are getting an
address error exception.  That would be the place to install such a handler,
but you would have to write an instruction decoder that would look at the
stack, figure out where the bad instruction was, decode that instruction to
figure out if it was the first operand, the second operand, or both that
caused the problem, fix it, do the instruction, change the stack a bit to
return to the instruction after the one that caused the problem, and then
do an RTE (return from exception) instruction.  Pretty nasty.  I think your
problems might be solved if you went to the 68020 processor that detects this
mis-alignment in the chip and does the right thing, but that to has obvious
problems and costs.

The first brute-force method of typedef'ing everything might work, but then
you might have to tweak all the code so that it still runs properly.  The
best thing to do is the most tedious.  Go through each exception by hand,
figure out what line of source caused the problem, and then change it.  No
fun, but I think you are kind of on your own for this one.  Good luck.

>Roger Levy
>...!rl@groucho.ATT.COM

   -dave

thomas@uplog.se (Thomas Tornblom) (08/08/90)

In article <1990Aug7.183302.26585@cbnewsl.att.com> rl@cbnewsl.att.com (roger.h.levy) writes:


   We have a substantial amount of C code originally targeted to a 68008
   system and now being ported to a 68000 system.  In the past, we have
   casted character pointers to integer pointers in some situations and
   then dereferenced the pointer.  Although this works OK with a 68008,
   it will result in a bus error on our 68000 target if the address of
   the data is odd.  Since we need to correct our code, I was wondering
   whether a tool exists that can identify instances of such statements.
   BTW, I checked my K&R and noted the warning about possible addressing
   errors as a result of this practice.  We realize the error of our
   ways so no further scolding is necessary.

   Roger Levy
   ...!rl@groucho.ATT.COM

Are you sure it worked on the 68008 and not on the 68000?
As I recall both the 68008 and the 68000 will generate an address error
when trying to access anything wider than a byte on an odd address.
I checked the 1983 "16-bit microprocessors data manual" from Moto and
it says that the 68000 and 68008 have equal programmer models.

Thomas
-- 
Real life:	Thomas Tornblom		Email:	thomas@uplog.se
Snail mail:	TeleLOGIC Uppsala AB		Phone:	+46 18 189406
		Box 1218			Fax:	+46 18 132039
		S - 751 42 Uppsala, Sweden

ckp@grebyn.com (Checkpoint Technologies) (08/09/90)

In article <1990Aug7.183302.26585@cbnewsl.att.com> rl@cbnewsl.att.com (roger.h.levy) writes:
>casted character pointers to integer pointers in some situations and
>then dereferenced the pointer.  Although this works OK with a 68008,
>it will result in a bus error on our 68000 target if the address of
>the data is odd.

I could swear that the 68008 also enforced even alignment of word and
long data objects; at least that's what my 68000/68008/68010 manual
says.  (I don't have it handy, or I'd look it up.)  If that's truly the
case then you can go ahead and run the same code; if it was wrong then
it would have caused address-error exceptions on the 68008 too.
-- 
First comes the logo: C H E C K P O I N T  T E C H N O L O G I E S      / /  
                                                                    \\ / /    
Then, the disclaimer:  All expressed opinions are, indeed, opinions. \  / o
Now for the witty part:    I'm pink, therefore, I'm spam!             \/