2013-05-23 14:52:29 +02:00
|
|
|
/* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
|
2001-04-01 05:03:41 +00:00
|
|
|
*
|
2009-05-26 22:23:44 +02:00
|
|
|
* This library is free software; you can redistribute it and/or
|
2009-06-17 00:22:09 +01:00
|
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 3 of
|
|
|
|
|
* the License, or (at your option) any later version.
|
2001-04-01 05:03:41 +00:00
|
|
|
*
|
2009-06-17 00:22:09 +01:00
|
|
|
* This library is distributed in the hope that it will be useful, but
|
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
2009-05-26 22:23:44 +02:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
2001-04-01 05:03:41 +00:00
|
|
|
*
|
2009-05-26 22:23:44 +02:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2009-06-17 00:22:09 +01:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
|
|
* 02110-1301 USA
|
2009-05-26 22:23:44 +02:00
|
|
|
*/
|
2001-04-01 05:03:41 +00:00
|
|
|
|
2008-05-20 11:46:52 +02:00
|
|
|
#if HAVE_CONFIG_H
|
|
|
|
|
# include <config.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
#include <string.h>
|
2009-05-26 22:23:44 +02:00
|
|
|
|
|
|
|
|
#include "_scm.h"
|
2011-02-10 21:11:47 +01:00
|
|
|
#include "threads.h"
|
2001-04-01 05:03:41 +00:00
|
|
|
#include "instructions.h"
|
|
|
|
|
|
2011-02-10 21:11:47 +01:00
|
|
|
|
2013-07-19 09:55:20 +02:00
|
|
|
SCM_SYMBOL (sym_left_arrow, "<-");
|
|
|
|
|
SCM_SYMBOL (sym_bang, "!");
|
|
|
|
|
|
|
|
|
|
|
2013-05-23 14:52:29 +02:00
|
|
|
#define FOR_EACH_INSTRUCTION_WORD_TYPE(M) \
|
|
|
|
|
M(X32) \
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
M(X8_S24) \
|
|
|
|
|
M(X8_F24) \
|
|
|
|
|
M(X8_L24) \
|
|
|
|
|
M(X8_C24) \
|
|
|
|
|
M(X8_S8_I16) \
|
|
|
|
|
M(X8_S12_S12) \
|
|
|
|
|
M(X8_S12_C12) \
|
|
|
|
|
M(X8_C12_C12) \
|
|
|
|
|
M(X8_F12_F12) \
|
|
|
|
|
M(X8_S8_S8_S8) \
|
|
|
|
|
M(X8_S8_C8_S8) \
|
|
|
|
|
M(X8_S8_S8_C8) \
|
|
|
|
|
M(C8_C24) \
|
|
|
|
|
M(C32) /* Unsigned. */ \
|
2013-05-23 14:52:29 +02:00
|
|
|
M(I32) /* Immediate. */ \
|
|
|
|
|
M(A32) /* Immediate, high bits. */ \
|
|
|
|
|
M(B32) /* Immediate, low bits. */ \
|
2015-11-20 16:14:32 +01:00
|
|
|
M(AF32) /* Immediate double, high bits. */ \
|
|
|
|
|
M(BF32) /* Immediate double, low bits. */ \
|
|
|
|
|
M(AU32) /* Immediate uint64, high bits. */ \
|
|
|
|
|
M(BU32) /* Immediate uint64, low bits. */ \
|
Untag values and indexes for all bytevector instructions
* libguile/vm-engine.c (bv-s8-ref, bv-s16-ref, bv-s32-ref, bv-s64-ref):
Unbox index and return unboxed S32 value.
(bv-s8-set!, bv-s16-set!, bv-s32-set!, bv-s64-set!): Unbox index and
take unboxed S32 value.
(bv-u8-ref, bv-u16-ref, bv-u32-ref, bv-u64-ref)
(bv-s8-set!, bv-s16-set!, bv-s32-set!, bv-s64-set!): Likewise, but
with unsigned values.
(bv-f32-ref, bv-f32-set!, bv-f64-ref, bv-f64-set!): Use memcpy to
access the value so we don't have to think about alignment. GCC will
inline this to a single instruction on architectures that support
unaligned access.
* libguile/vm.c (vm_error_out_of_range_uint64)
(vm_error_out_of_range_int64): New helpers.
* module/language/cps/slot-allocation.scm (compute-var-representations):
All bytevector ref operations produce untagged values.
* module/language/cps/types.scm (define-bytevector-accessors): Update
for bytevector untagged indices and values.
* module/language/cps/utils.scm (compute-constant-values): Fix s64
case.
* module/language/tree-il/compile-cps.scm (convert): Box results of all
bytevector accesses, and unbox incoming indices and values.
2015-11-21 11:50:15 +01:00
|
|
|
M(AS32) /* Immediate int64, high bits. */ \
|
|
|
|
|
M(BS32) /* Immediate int64, low bits. */ \
|
2013-05-23 14:52:29 +02:00
|
|
|
M(N32) /* Non-immediate. */ \
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
M(R32) /* Scheme value (indirected). */ \
|
2013-05-23 14:52:29 +02:00
|
|
|
M(L32) /* Label. */ \
|
|
|
|
|
M(LO32) /* Label with offset. */ \
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
M(B1_C7_L24) \
|
2013-05-23 14:52:29 +02:00
|
|
|
M(B1_X7_L24) \
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
M(B1_X7_C24) \
|
|
|
|
|
M(B1_X7_S24) \
|
|
|
|
|
M(B1_X7_F24) \
|
Various RTL VM and calling convention tweaks
* libguile/instructions.c (FOR_EACH_INSTRUCTION_WORD_TYPE): Allow for
five-word instructions, and for new instruction word types.
* libguile/vm-engine.c (RETURN_ONE_VALUE): Instead of returning the
value in the fixed part of the call frame, return it in the same place
multiple-value returns go: from slot 1.
(BR_ARITHMETIC): Allow arithmetic tests to be negated.
(rtl_vm_engine): Change calling convention to use the same location
for single and multiple-value returns. Renumber all instructions.
(halt, halt/values): Fold into a single instruction (halt).
(call): Take the location of the procedure instead of the location of
the call frame. Also take the number of args, and reset the sp before
jumping to the procedure, so as to indicate the number of arguments.
(call/values): Remove, as the new calling convention has RA == MVRA.
(tail-call): Require the procedure to be shuffled down already, and
take "nlocals" as an arg instead of "nargs".
(receive, receive-values): New instructions, for receiving returned
values from calls.
(return-values): Rename from return/values. Remove "values".
(alloc-frame): Rename from reserve-locals.
(reset-frame): New instruction.
(drop-locals): Remove.
(br-if-=, br-if-<, br-if-<=): Allow these instructions to be
negatable.
(br-if->, br-if->=): Remove. Probably a bad idea, given NaN.
(box-ref): Don't bother trying to do a reverse lookup -- the
toplevel-box, module-box, and resolve instructions should handle
that.
(resolve): Add arg to check that the variable is bound.
(toplevel-box, module-box): New instructions, replacing toplevel-ref,
toplevel-set, module-ref, and module-set.
* libguile/vm.c (rtl_boot_continuation_code, rtl_values_code): Adapt to
instruction set changes.
* module/Makefile.am: Make the assembler and disassembler dependent on
vm-operations.h.
* module/system/vm/assembler.scm:
* module/system/vm/disassembler.scm: Adapt to instruction changes and
new instruction word kinds.
* test-suite/tests/rtl.test: Adapt to instruction set changes.
2013-08-11 16:42:06 +02:00
|
|
|
M(B1_X31)
|
2013-05-23 14:52:29 +02:00
|
|
|
|
2015-11-20 16:14:32 +01:00
|
|
|
#define TYPE_WIDTH 6
|
2013-05-23 14:52:29 +02:00
|
|
|
|
|
|
|
|
enum word_type
|
|
|
|
|
{
|
|
|
|
|
#define ENUM(type) type,
|
|
|
|
|
FOR_EACH_INSTRUCTION_WORD_TYPE (ENUM)
|
|
|
|
|
#undef ENUM
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static SCM word_type_symbols[] =
|
|
|
|
|
{
|
|
|
|
|
#define FALSE(type) SCM_BOOL_F,
|
|
|
|
|
FOR_EACH_INSTRUCTION_WORD_TYPE (FALSE)
|
|
|
|
|
#undef FALSE
|
|
|
|
|
};
|
|
|
|
|
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
#define OP(n,type) (((type) + 1) << (n*TYPE_WIDTH))
|
2013-05-23 14:52:29 +02:00
|
|
|
|
|
|
|
|
/* The VM_DEFINE_OP macro uses a CPP-based DSL to describe what kinds of
|
2013-11-19 20:45:57 +01:00
|
|
|
arguments each instruction takes. This piece of code is the only
|
2013-05-23 14:52:29 +02:00
|
|
|
bit that actually interprets that language. These macro definitions
|
2015-11-20 16:14:32 +01:00
|
|
|
encode the operand types into bits in a 64-bit integer.
|
2013-05-23 14:52:29 +02:00
|
|
|
|
2013-11-19 20:45:57 +01:00
|
|
|
(instruction-list) parses those encoded values into lists of symbols,
|
2015-11-20 16:14:32 +01:00
|
|
|
one for each 64-bit word that the operator takes. This list is used
|
2013-11-19 20:45:57 +01:00
|
|
|
by Scheme to generate assemblers and disassemblers for the
|
|
|
|
|
instructions. */
|
2013-05-23 14:52:29 +02:00
|
|
|
|
2015-11-20 16:14:32 +01:00
|
|
|
#define NOP SCM_T_UINT64_MAX
|
2013-05-23 14:52:29 +02:00
|
|
|
#define OP1(type0) \
|
|
|
|
|
(OP (0, type0))
|
|
|
|
|
#define OP2(type0, type1) \
|
|
|
|
|
(OP (0, type0) | OP (1, type1))
|
|
|
|
|
#define OP3(type0, type1, type2) \
|
|
|
|
|
(OP (0, type0) | OP (1, type1) | OP (2, type2))
|
|
|
|
|
#define OP4(type0, type1, type2, type3) \
|
|
|
|
|
(OP (0, type0) | OP (1, type1) | OP (2, type2) | OP (3, type3))
|
Various RTL VM and calling convention tweaks
* libguile/instructions.c (FOR_EACH_INSTRUCTION_WORD_TYPE): Allow for
five-word instructions, and for new instruction word types.
* libguile/vm-engine.c (RETURN_ONE_VALUE): Instead of returning the
value in the fixed part of the call frame, return it in the same place
multiple-value returns go: from slot 1.
(BR_ARITHMETIC): Allow arithmetic tests to be negated.
(rtl_vm_engine): Change calling convention to use the same location
for single and multiple-value returns. Renumber all instructions.
(halt, halt/values): Fold into a single instruction (halt).
(call): Take the location of the procedure instead of the location of
the call frame. Also take the number of args, and reset the sp before
jumping to the procedure, so as to indicate the number of arguments.
(call/values): Remove, as the new calling convention has RA == MVRA.
(tail-call): Require the procedure to be shuffled down already, and
take "nlocals" as an arg instead of "nargs".
(receive, receive-values): New instructions, for receiving returned
values from calls.
(return-values): Rename from return/values. Remove "values".
(alloc-frame): Rename from reserve-locals.
(reset-frame): New instruction.
(drop-locals): Remove.
(br-if-=, br-if-<, br-if-<=): Allow these instructions to be
negatable.
(br-if->, br-if->=): Remove. Probably a bad idea, given NaN.
(box-ref): Don't bother trying to do a reverse lookup -- the
toplevel-box, module-box, and resolve instructions should handle
that.
(resolve): Add arg to check that the variable is bound.
(toplevel-box, module-box): New instructions, replacing toplevel-ref,
toplevel-set, module-ref, and module-set.
* libguile/vm.c (rtl_boot_continuation_code, rtl_values_code): Adapt to
instruction set changes.
* module/Makefile.am: Make the assembler and disassembler dependent on
vm-operations.h.
* module/system/vm/assembler.scm:
* module/system/vm/disassembler.scm: Adapt to instruction changes and
new instruction word kinds.
* test-suite/tests/rtl.test: Adapt to instruction set changes.
2013-08-11 16:42:06 +02:00
|
|
|
#define OP5(type0, type1, type2, type3, type4) \
|
|
|
|
|
(OP (0, type0) | OP (1, type1) | OP (2, type2) | OP (3, type3) | OP (4, type4))
|
2013-05-23 14:52:29 +02:00
|
|
|
|
|
|
|
|
#define OP_DST (1 << (TYPE_WIDTH * 5))
|
|
|
|
|
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
#define WORD_TYPE_AND_FLAG(n, word) \
|
2013-05-23 14:52:29 +02:00
|
|
|
(((word) >> ((n) * TYPE_WIDTH)) & ((1 << TYPE_WIDTH) - 1))
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
#define WORD_TYPE(n, word) \
|
|
|
|
|
(WORD_TYPE_AND_FLAG (n, word) - 1)
|
|
|
|
|
#define HAS_WORD(n, word) \
|
|
|
|
|
(WORD_TYPE_AND_FLAG (n, word) != 0)
|
2013-05-23 14:52:29 +02:00
|
|
|
|
2013-11-21 22:51:38 +01:00
|
|
|
/* Scheme interface */
|
2011-02-10 21:11:47 +01:00
|
|
|
|
2013-11-21 22:51:38 +01:00
|
|
|
static SCM
|
2015-11-20 16:14:32 +01:00
|
|
|
parse_instruction (scm_t_uint8 opcode, const char *name, scm_t_uint64 meta)
|
2013-05-23 14:52:29 +02:00
|
|
|
{
|
2013-11-21 22:51:38 +01:00
|
|
|
SCM tail = SCM_EOL;
|
|
|
|
|
int len;
|
|
|
|
|
|
|
|
|
|
/* Format: (name opcode word0 word1 ...) */
|
|
|
|
|
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
if (HAS_WORD (4, meta))
|
2013-11-21 22:51:38 +01:00
|
|
|
len = 5;
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
else if (HAS_WORD (3, meta))
|
2013-11-21 22:51:38 +01:00
|
|
|
len = 4;
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
else if (HAS_WORD (2, meta))
|
2013-11-21 22:51:38 +01:00
|
|
|
len = 3;
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
else if (HAS_WORD (1, meta))
|
2013-11-21 22:51:38 +01:00
|
|
|
len = 2;
|
Prepare for SP-addressed locals
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
2015-10-20 20:06:40 +02:00
|
|
|
else if (HAS_WORD (0, meta))
|
2013-11-21 22:51:38 +01:00
|
|
|
len = 1;
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
switch (len)
|
2013-05-23 14:52:29 +02:00
|
|
|
{
|
2013-11-21 22:51:38 +01:00
|
|
|
case 5:
|
|
|
|
|
tail = scm_cons (word_type_symbols[WORD_TYPE (4, meta)], tail);
|
|
|
|
|
case 4:
|
|
|
|
|
tail = scm_cons (word_type_symbols[WORD_TYPE (3, meta)], tail);
|
|
|
|
|
case 3:
|
|
|
|
|
tail = scm_cons (word_type_symbols[WORD_TYPE (2, meta)], tail);
|
|
|
|
|
case 2:
|
|
|
|
|
tail = scm_cons (word_type_symbols[WORD_TYPE (1, meta)], tail);
|
|
|
|
|
case 1:
|
|
|
|
|
tail = scm_cons (word_type_symbols[WORD_TYPE (0, meta)], tail);
|
|
|
|
|
default:
|
|
|
|
|
tail = scm_cons ((meta & OP_DST) ? sym_left_arrow : sym_bang, tail);
|
|
|
|
|
tail = scm_cons (scm_from_int (opcode), tail);
|
|
|
|
|
tail = scm_cons (scm_from_utf8_symbol (name), tail);
|
|
|
|
|
return tail;
|
2013-05-23 14:52:29 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-19 20:45:57 +01:00
|
|
|
SCM_DEFINE (scm_instruction_list, "instruction-list", 0, 0, 0,
|
2013-05-23 14:52:29 +02:00
|
|
|
(void),
|
|
|
|
|
"")
|
2013-11-19 20:45:57 +01:00
|
|
|
#define FUNC_NAME s_scm_instruction_list
|
2013-05-23 14:52:29 +02:00
|
|
|
{
|
|
|
|
|
SCM list = SCM_EOL;
|
2013-11-21 22:51:38 +01:00
|
|
|
|
|
|
|
|
#define INIT(opcode, tag, name, meta) \
|
|
|
|
|
if (name) list = scm_cons (parse_instruction (opcode, name, meta), list);
|
|
|
|
|
FOR_EACH_VM_OPERATION (INIT);
|
|
|
|
|
#undef INIT
|
2013-05-23 14:52:29 +02:00
|
|
|
|
|
|
|
|
return scm_reverse_x (list, SCM_EOL);
|
|
|
|
|
}
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
void
|
|
|
|
|
scm_bootstrap_instructions (void)
|
|
|
|
|
{
|
2010-03-16 21:18:12 +01:00
|
|
|
scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
|
|
|
|
|
"scm_init_instructions",
|
2009-03-27 18:40:15 -07:00
|
|
|
(scm_t_extension_init_func)scm_init_instructions,
|
|
|
|
|
NULL);
|
2013-11-19 20:45:57 +01:00
|
|
|
}
|
2013-05-23 14:52:29 +02:00
|
|
|
|
2013-11-19 20:45:57 +01:00
|
|
|
void
|
|
|
|
|
scm_init_instructions (void)
|
|
|
|
|
{
|
2013-05-23 14:52:29 +02:00
|
|
|
#define INIT(type) \
|
|
|
|
|
word_type_symbols[type] = scm_from_utf8_symbol (#type);
|
|
|
|
|
FOR_EACH_INSTRUCTION_WORD_TYPE (INIT)
|
|
|
|
|
#undef INIT
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
#ifndef SCM_MAGIC_SNARFER
|
2009-03-16 23:39:29 +01:00
|
|
|
#include "libguile/instructions.x"
|
2001-04-01 05:03:41 +00:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Local Variables:
|
|
|
|
|
c-file-style: "gnu"
|
|
|
|
|
End:
|
|
|
|
|
*/
|