mirror of
https://github.com/netwide-assembler/nasm
synced 2026-08-26 16:23:04 -04:00
saa: make saa_wleb128[us]() take appropriate types; recode
Make saa_wleb128[us]() take uint64_t and int64_t, respectively, rather than int. Notably, if saa_wleb128u() were to receive negative int, it would have looped forever. Recode these functions in a style more consistent with NASM code in general, and possibly a bit simpler. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
parent
9fdc7eab6e
commit
8d4733962e
2 changed files with 51 additions and 48 deletions
|
|
@ -57,8 +57,8 @@ void saa_write8(struct SAA *s, uint8_t v);
|
|||
void saa_write16(struct SAA *s, uint16_t v);
|
||||
void saa_write32(struct SAA *s, uint32_t v);
|
||||
void saa_write64(struct SAA *s, uint64_t v);
|
||||
void saa_wleb128u(struct SAA *, int); /* write unsigned LEB128 value */
|
||||
void saa_wleb128s(struct SAA *, int); /* write signed LEB128 value */
|
||||
void saa_writeaddr(struct SAA *, uint64_t, size_t);
|
||||
void saa_wleb128u(struct SAA *, uint64_t v); /* unsigned LEB128 value */
|
||||
void saa_wleb128s(struct SAA *, int64_t v); /* signed LEB128 value */
|
||||
void saa_writeaddr(struct SAA *, uint64_t, size_t); /* specific size integer */
|
||||
|
||||
#endif /* NASM_SAA_H */
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "compiler.h"
|
||||
#include "nasmlib.h"
|
||||
#include "ilog2.h"
|
||||
#include "saa.h"
|
||||
|
||||
/* Aggregate SAA components smaller than this */
|
||||
|
|
@ -299,55 +300,57 @@ void saa_writeaddr(struct SAA *s, uint64_t v, size_t len)
|
|||
saa_wbytes(s, &v, len);
|
||||
}
|
||||
|
||||
/* write unsigned LEB128 value to SAA */
|
||||
void saa_wleb128u(struct SAA *psaa, int value)
|
||||
/*
|
||||
* Write an LEB128 value to an SAA. Each byte contains 7 bits of
|
||||
* payload in littleendian order, with the topmost bit indicating
|
||||
* continuation.
|
||||
*
|
||||
* For the signed format, the sign bit needs to be included, even if
|
||||
* it zero, so may generate an encoding that would be invalid for
|
||||
* the unsigned format, e.g 127:
|
||||
*
|
||||
* unsigned: 7F
|
||||
* signed: FF 00
|
||||
*
|
||||
* Thus, the >> 6 instead of >> 7 in the exit test for the signed
|
||||
* version.
|
||||
*/
|
||||
void saa_wleb128u(struct SAA *s, uint64_t value)
|
||||
{
|
||||
char temp[64], *ptemp;
|
||||
uint8_t buf[sizeof(value)*2]; /* Very conservative allocation :) */
|
||||
uint8_t *p = buf;
|
||||
uint8_t byte;
|
||||
int len;
|
||||
|
||||
ptemp = temp;
|
||||
len = 0;
|
||||
do {
|
||||
while (1) {
|
||||
byte = value & 127;
|
||||
value >>= 7;
|
||||
if (value != 0) /* more bytes to come */
|
||||
byte |= 0x80;
|
||||
*ptemp = byte;
|
||||
ptemp++;
|
||||
len++;
|
||||
} while (value != 0);
|
||||
saa_wbytes(psaa, temp, len);
|
||||
}
|
||||
|
||||
/* write signed LEB128 value to SAA */
|
||||
void saa_wleb128s(struct SAA *psaa, int value)
|
||||
{
|
||||
char temp[64], *ptemp;
|
||||
uint8_t byte;
|
||||
bool more, negative;
|
||||
int size, len;
|
||||
|
||||
ptemp = temp;
|
||||
more = 1;
|
||||
negative = (value < 0);
|
||||
size = sizeof(int) * 8;
|
||||
len = 0;
|
||||
while (more) {
|
||||
byte = value & 0x7f;
|
||||
value >>= 7;
|
||||
if (negative)
|
||||
/* sign extend */
|
||||
value |= -(1 << (size - 7));
|
||||
/* sign bit of byte is second high order bit (0x40) */
|
||||
if ((value == 0 && !(byte & 0x40)) ||
|
||||
((value == -1) && (byte & 0x40)))
|
||||
more = 0;
|
||||
else
|
||||
byte |= 0x80;
|
||||
*ptemp = byte;
|
||||
ptemp++;
|
||||
len++;
|
||||
if (!value) {
|
||||
*p++ = byte;
|
||||
break;
|
||||
}
|
||||
byte |= 0x80;
|
||||
*p++ = byte;
|
||||
}
|
||||
saa_wbytes(psaa, temp, len);
|
||||
saa_wbytes(s, buf, p-buf);
|
||||
}
|
||||
|
||||
/* write a signed LEB128 value to SAA */
|
||||
void saa_wleb128s(struct SAA *s, int64_t value)
|
||||
{
|
||||
uint8_t buf[sizeof(value)*2]; /* Very conservative allocation :) */
|
||||
uint8_t *p = buf;
|
||||
uint8_t byte;
|
||||
int64_t sign = value >> 63;
|
||||
|
||||
while (1) {
|
||||
byte = value & 127;
|
||||
if ((value >> 6) == sign) {
|
||||
*p++ = byte;
|
||||
break;
|
||||
}
|
||||
value >>= 7;
|
||||
byte |= 0x80;
|
||||
*p++ = byte;
|
||||
}
|
||||
saa_wbytes(s, buf, p-buf);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue