diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-04-12 19:57:17 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-04-12 19:57:17 -0700 |
commit | 69d9874359752a68a61055c1117a06aae7cb4f1d (patch) | |
tree | 8a1b2c8402ea0afee63505e453b6c72ef60572bf /buf.c | |
parent | 0bdcbc08658036dbf46142c1fb41e320e6019148 (diff) | |
download | txr-69d9874359752a68a61055c1117a06aae7cb4f1d.tar.gz txr-69d9874359752a68a61055c1117a06aae7cb4f1d.tar.bz2 txr-69d9874359752a68a61055c1117a06aae7cb4f1d.zip |
compile-file: need endian mark in .tlo files.
VM machine code is endian-specific: it consists of 32 bit
instruction words which are 32 bit in the local byte order.
Thus code assembled on a little-endian machine won't run
on a big endian-machine, or vice versa: unless we identify
the situation and byte-swap the code when we load it.
* buf.c (buf_swap32): New function.
* buf.h (buf_swap32): Declared.
* parser.c (read_file_common): Decode the third element from
the version: a Boolean indicating big endian, if true.
If the object file's endian is opposite from our endian, then
byte swap the code.
* itypes.c (itypes_init): Oops, calculation of
itypes_little_endian was broken due to classic C =/== typo.
Luckily, nothing has used this flag so far; it's been waiting
for this first use. I caught this due to testing on a PPC64
box.
* share/txr/stdlib/compiler.tl (%big-endian%, %tlo-ver%): New
variables.
(usr:compile-file): The file version comes from %tlo-ver% now,
which includes the big-endian flag.
Diffstat (limited to 'buf.c')
-rw-r--r-- | buf.c | 14 |
1 files changed, 14 insertions, 0 deletions
@@ -914,6 +914,20 @@ val get_buf_from_stream(val stream) return s->buf; } +void buf_swap32(val buf) +{ + val self = lit("buf-swap32"); + struct buf *b = buf_handle(buf, self); + mem_t *data = b->data, *end = data + c_num(b->len); + + for (; data + 3 < end; data += 4) { + u32_t sw32 = *coerce(u32_t *, data); + sw32 = ((sw32 & 0xFF00FF00U) >> 8) | ((sw32 & 0x00FF00FFU) << 8); + sw32 = ((sw32 & 0xFFFF0000U) >> 16) | ((sw32 & 0x0000FFFFU) << 16); + *coerce(u32_t *, data) = sw32; + } +} + void buf_init(void) { reg_fun(intern(lit("make-buf"), user_package), func_n3o(make_buf, 1)); |