Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo
Close
From: Philipp Klaus Krause <pkk@sp...>  20060927 21:49:22

BEGIN PGP SIGNED MESSAGE Hash: SHA1 I'd like to add a new token: SRA, arithmetic shift right. This token would be emitted in geniCodeDivision in SDCCicode.c I'm trying to implement #1307995: Use shifts instead of division for divisions with signed left operands. Does that mean that I have to write code generation for this token for every port in gen.c? Is there a way to handle this token only in one port for now and then gradually add it to other ports? Philipp BEGIN PGP SIGNATURE Version: GnuPG v1.4.5 (GNU/Linux) Comment: Using GnuPG with Mozilla  http://enigmail.mozdev.org iD8DBQFFGvHcbtUV+xsoLpoRAgG/AKDMzE9fKtPUhbgPVtPinDvA2Zr0zgCbBNB/ ETfuzQd2uzn73cj2u66FF5g= =G8qT END PGP SIGNATURE 
From: Frieder Ferlemann <frieder.ferlemann@we...>  20060928 08:03:14

Philipp Klaus Krause schrieb: > I'd like to add a new token: SRA, arithmetic shift right. > This token would be emitted in geniCodeDivision in SDCCicode.c > I'm trying to implement #1307995: Use shifts instead of division for > divisions with signed left operands. > Does that mean that I have to write code generation for this token for > every port in gen.c? > Is there a way to handle this token only in one port for now and then > gradually add it to other ports? you could probably use f.e. Erik's checkins on 20031106 when SWAP was added as a reference (hasExtBitOp()). Greetings, Frieder 
From: Maarten Brock <sourceforge.brock@ds...>  20060928 09:06:06

Philipp, This is already an icode: RIGHT_OP. AFAIK it can handle both signed and unsigned shifts. I don't know why it only converts div to shift for an unsigned left operand. Try removing IS_UNSIGNED(letype) from the check in geniCodeDivision() in SDCCicode.c. Run regression tests if possible to see they all pass and also have a look at the bytes and clock ticks to see if it really is an improvement. Maarten > BEGIN PGP SIGNED MESSAGE > Hash: SHA1 > > I'd like to add a new token: SRA, arithmetic shift right. > This token would be emitted in geniCodeDivision in SDCCicode.c > I'm trying to implement #1307995: Use shifts instead of division for > divisions with signed left operands. > Does that mean that I have to write code generation for this token for > every port in gen.c? > Is there a way to handle this token only in one port for now and then > gradually add it to other ports? > > Philipp > BEGIN PGP SIGNATURE > Version: GnuPG v1.4.5 (GNU/Linux) > Comment: Using GnuPG with Mozilla  http://enigmail.mozdev.org > > iD8DBQFFGvHcbtUV+xsoLpoRAgG/AKDMzE9fKtPUhbgPVtPinDvA2Zr0zgCbBNB/ > ETfuzQd2uzn73cj2u66FF5g=3D > =3DG8qT > END PGP SIGNATURE 
From: Philipp Klaus Krause <pkk@sp...>  20060928 09:41:30

BEGIN PGP SIGNED MESSAGE Hash: SHA1 Maarten Brock schrieb: > Philipp, > > This is already an icode: RIGHT_OP. AFAIK it can handle both signed and > unsigned shifts. I don't know why it only converts div to shift for an > unsigned left operand. I looked at different port's gen.c; some do arithmetic right shifts for signed operands (pic16), some do logical shifts for both (z80), so I assumed RIGHT_OP was undefined for signed left operands. According to the C99 standard x >> y is implementationdefined for x < 0 (x << y is undefined for x < 0). If there's a processor where logical shifts are faster than arithmetic shifts, it would make sense to have different tokens, so arithmetic shifts would be needed only to replace divisions. Philipp BEGIN PGP SIGNATURE Version: GnuPG v1.4.5 (GNU/Linux) Comment: Using GnuPG with Mozilla  http://enigmail.mozdev.org iD8DBQFFG5jEbtUV+xsoLpoRAs6DAJsGGNwcf5e5wUIaVfqzQR/rZP73FQCgwX9V DM3BoaZIRGInxACeTIXPyJU= =WXrE END PGP SIGNATURE 
From: Maarten Brock <sourceforge.brock@ds...>  20060928 10:36:07

Philipp, > I looked at different port's gen.c; some do arithmetic right shifts for > signed operands (pic16), some do logical shifts for both (z80), so I > assumed RIGHT_OP was undefined for signed left operands. > According to the C99 standard x >> y is implementationdefined for x <= 0 > (x << y is undefined for x < 0). I was not aware of that. > If there's a processor where logical shifts are faster than arithmetic > shifts, it would make sense to have different tokens, so arithmetic > shifts would be needed only to replace divisions. I would vote to make all ports always use an arithmetic shift for signed operands. If the user wants the faster logical shift he should use unsigned operands. Maarten 
From: Philipp Klaus Krause <pkk@sp...>  20060928 11:48:42

BEGIN PGP SIGNED MESSAGE Hash: SHA1 Maarten Brock schrieb: > I would vote to make all ports always use an arithmetic shift for signed > operands. If the user wants the faster logical shift he should use > unsigned operands. > > Maarten I think that would be ok. pic16, ds390 and mcs51 do it that way already (though ds390 and mcs51 have conflicting comments in gen.c) I think I could change the z80 port. I don't know about the pic and hc08 port. They have conflicting comments (same as mcs51) and the code doesn't seem obvious to me. The conflicting comments are /* if signed then we do it the hard way preserve the sign bit moving it inwards */ /* signed & unsigned types are treated the same : i.e. the signed is NOT propagated inwards : quoting from the ANSI  standard : "for E1 >> E2, is equivalent to division by 2**E2 if unsigned or if it has a nonnegative value, otherwise the result is implementation defined ", MY definition is that the sign does not get propagated */ Philipp BEGIN PGP SIGNATURE Version: GnuPG v1.4.5 (GNU/Linux) Comment: Using GnuPG with Mozilla  http://enigmail.mozdev.org iD8DBQFFG7aRbtUV+xsoLpoRAnz0AJ9EvpQVlbzlAwITOQnu50u6L+73SQCeIOid uCe33TpCy2yK4+d01Vh8fr8= =CdIZ END PGP SIGNATURE 
From: Raphael Neider <rneider@we...>  20060928 12:39:17

> I think that would be ok. pic16, ds390 and mcs51 do it that way already > (though ds390 and mcs51 have conflicting comments in gen.c) > I think I could change the z80 port. > I don't know about the pic and hc08 port. They have conflicting comments > (same as mcs51) and the code doesn't seem obvious to me. > > The conflicting comments are > /* if signed then we do it the hard way preserve the > sign bit moving it inwards */ > /* signed & unsigned types are treated the same : i.e. the > signed is NOT propagated inwards : quoting from the > ANSI  standard : "for E1 >> E2, is equivalent to division > by 2**E2 if unsigned or if it has a nonnegative value, > otherwise the result is implementation defined ", MY definition > is that the sign does not get propagated */ > The pic14 port takes a sort of queer approach: First, the left operand is promoted/demoted to fill/fit into result, preserving left's sign in the process. It then rightshifts 'result', preserving its respective sign only if 'result' is signed. For "u8 result, s16 left" this acts like result = (u8)left >> right with unsigned right shift and prevents arbitrary bits from being shifted in. Suppose we had 0x0280 >> 1. 0x0280 is positive, but would crop to 0x80, which is 128. Shifting signed now produces 0xC0 (64), although 0x0280 >> 1 would have yielded 0x0140, cropping to 0x40 != 0xC0. On the other hand, 0x280 >> 2 should yield 0x00A0, cropped to 0xA0, but (from reading the code, not tried it) this is turned into 0x80>>2 == 0x20 by the pic14 port. "Correct" behaviour calls for a lot more code being generated, not sure if that is desired... HTH and waiting for further orders ;) Raphael 
From: Philipp Klaus Krause <pkk@sp...>  20060928 13:09:43

BEGIN PGP SIGNED MESSAGE Hash: SHA1 Raphael Neider schrieb: > > The pic14 port takes a sort of queer approach: > First, the left operand is promoted/demoted to fill/fit into result, > preserving left's sign in the process. It then rightshifts 'result', > preserving its respective sign only if 'result' is signed. > For "u8 result, s16 left" this acts like result = (u8)left >> right with > unsigned right shift and prevents arbitrary bits from being shifted in. > > Suppose we had 0x0280 >> 1. 0x0280 is positive, but would crop to 0x80, > which is 128. Shifting signed now produces 0xC0 (64), although > 0x0280 >> 1 would have yielded 0x0140, cropping to 0x40 != 0xC0. > On the other hand, 0x280 >> 2 should yield 0x00A0, cropped to 0xA0, but > (from reading the code, not tried it) this is turned into 0x80>>2 == > 0x20 by the pic14 port. I think this is a bug:  From C99 specification: "The type of the result is the promoted left operand." and "It E1 has an unsigned type or E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2^(E2)." (talking about E1 >> E2). Philipp BEGIN PGP SIGNATURE Version: GnuPG v1.4.5 (GNU/Linux) Comment: Using GnuPG with Mozilla  http://enigmail.mozdev.org iD8DBQFFG8mObtUV+xsoLpoRAqN9AJ0VgMHXkdisa3ksXS7ndkHFqDKoDwCeJwZK Uptp9mwjzvqn22L+1T72/jU= =graF END PGP SIGNATURE 
From: Maarten Brock <sourceforge.brock@ds...>  20060928 20:28:27

Hi again, The pic14 approach is buggy in my opinion too. But then there are more bugs in the pic14, so why not this one ;) Let's leave it out of the discussion for now. I just had a look in regression test shifts.c function test2ShiftRight(). It tests the right shift operator with a negative operand and expects to get negative results. Since all stable ports pass this regression test I conclude that they all use an arithmetic shift right. Even pic16 passes this test. The comments in the sources are probably leftovers of times gone by and need to be updated. I'll try my proposed change to SDCCicode.c and see what the results are. Maarten > BEGIN PGP SIGNED MESSAGE > Hash: SHA1 > > Raphael Neider schrieb: > > > > > The pic14 port takes a sort of queer approach: > > First, the left operand is promoted/demoted to fill/fit into result, > > preserving left's sign in the process. It then rightshifts 'result', > > preserving its respective sign only if 'result' is signed. > > For "u8 result, s16 left" this acts like result = (u8)left >> right with > > unsigned right shift and prevents arbitrary bits from being shifted in. > > > > Suppose we had 0x0280 >> 1. 0x0280 is positive, but would crop to 0x80, > > which is 128. Shifting signed now produces 0xC0 (64), although > > 0x0280 >> 1 would have yielded 0x0140, cropping to 0x40 != 0xC0. > > On the other hand, 0x280 >> 2 should yield 0x00A0, cropped to 0xA0, but > > (from reading the code, not tried it) this is turned into 0x80>>2 == > > 0x20 by the pic14 port. > > I think this is a bug: >  From C99 specification: > "The type of the result is the promoted left operand." > and > "It E1 has an unsigned type or E1 has a signed type and a nonnegative > value, the value of the result is the integral part of the quotient of > E1 / 2^(E2)." (talking about E1 >> E2). > > Philipp 
From: Philipp Klaus Krause <pkk@sp...>  20060928 11:55:54

BEGIN PGP SIGNED MESSAGE Hash: SHA1 Sorry, it seems I was wrong. I took a closer look at the Z80 gen.c and it seems to generate arithmetic right shifts for signed operands. Philipp BEGIN PGP SIGNATURE Version: GnuPG v1.4.5 (GNU/Linux) Comment: Using GnuPG with Mozilla  http://enigmail.mozdev.org iD8DBQFFG7hEbtUV+xsoLpoRAsa+AJ9U41B5xzignoQf+RSBTu2fg6Mr9gCeJ/rj U/QrFYAV+sqW0pmo6Ck07Sg= =Qofz END PGP SIGNATURE 
From: Philipp Klaus Krause <pkk@sp...>  20061008 21:40:56

BEGIN PGP SIGNED MESSAGE Hash: SHA1 Maarten Brock schrieb: > Try removing IS_UNSIGNED(letype) from the check in geniCodeDivision() in > SDCCicode.c. Run regression tests if possible to see they all pass and > also have a look at the bytes and clock ticks to see if it really is an > improvement. I've tried. Regression tests fail. Then I looked at the C specification. We can't use an arithmetic right shift for division of signed integers. The C90 specification allowed this, C99 does not: "When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded." Philipp BEGIN PGP SIGNATURE Version: GnuPG v1.4.5 (GNU/Linux) Comment: Using GnuPG with Mozilla  http://enigmail.mozdev.org iD8DBQFFKXBibtUV+xsoLpoRAo1EAJ9xulTAEy0lVKHZ4qleIRTkVn8HdgCggXYd TTeocu095/A65TQs8btvT0M= =/ItR END PGP SIGNATURE 
From: sdccdevel <sdccdevel@be...>  20061009 07:57:00

> > Try removing IS_UNSIGNED(letype) from the check in geniCodeDivision() in > > SDCCicode.c. Run regression tests if possible to see they all pass and > > also have a look at the bytes and clock ticks to see if it really is an > > improvement. > > I've tried. Regression tests fail. If you want me to have a look please send me a `snv diff` of your working copy. > Then I looked at the C specification. > We can't use an arithmetic right shift for division of signed integers. > The C90 specification allowed this, C99 does not: > > "When integers are divided, the result of the / operator is the > algebraic quotient with any fractional part discarded." Hmm, I don't see a problem. What exactly don't you like? Bernhard 
From: Philipp Klaus Krause <pkk@sp...>  20061009 09:48:05

BEGIN PGP SIGNED MESSAGE Hash: SHA1 sdccdevel schrieb: >> >> "When integers are divided, the result of the / operator is the >> algebraic quotient with any fractional part discarded." > Hmm, I don't see a problem. What exactly don't you like? Discarding the fractional part means rounding towards zero. A division implemented by arithmetric rightshifts means rounding towards minus infinity. Philipp BEGIN PGP SIGNATURE Version: GnuPG v1.4.5 (GNU/Linux) Comment: Using GnuPG with Mozilla  http://enigmail.mozdev.org iD8DBQFFKhrPbtUV+xsoLpoRAliAAKDndY5S7C5SR5uP03GAL9AS4DiPfQCg1DZv 9swsTpO3UeO0mghO/Lwxc3w= =aeSN END PGP SIGNATURE 
From: Bernhard Held <sdccdevel@be...>  20061009 11:49:17
Attachments:
lddiv.c

> >> "When integers are divided, the result of the / operator is the > >> algebraic quotient with any fractional part discarded." > > Hmm, I don't see a problem. What exactly don't you like? > > Discarding the fractional part means rounding towards zero. A division > implemented by arithmetric rightshifts means rounding towards minus > infinity. Oh, yes, you're right. I just tried it in an example. Two ideas:  make the operand unsigned, do the shifting, and finally restore the sign  fix rounding by adding (divisor  1) to the dividend, if the dividend is negative. See me little program in the attachment  it seems to work. IMHO the additional overhead for the rounding is acceptable. Bernhard 