/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2004, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*
*/
#ifndef _LSAPIC_H
#define _LSAPIC_H
#include <xen/sched.h>
#include <asm/vmx_vcpu.h>
/*
*Delivery mode
*/
#define SAPIC_DELIV_SHIFT 8
#define SAPIC_FIXED 0x0
#define SAPIC_LOWEST_PRIORITY 0x1
#define SAPIC_PMI 0x2
#define SAPIC_NMI 0x4
#define SAPIC_INIT 0x5
#define SAPIC_EXTINT 0x7
/*
*Interrupt polarity
*/
#define SAPIC_POLARITY_SHIFT 13
#define SAPIC_POL_HIGH 0
#define SAPIC_POL_LOW 1
/*
*Trigger mode
*/
#define SAPIC_TRIGGER_SHIFT 15
#define SAPIC_EDGE 0
#define SAPIC_LEVEL 1
/*
* LSAPIC OFFSET
*/
#define PIB_LOW_HALF(ofst) !(ofst & (1 << 20))
#define PIB_OFST_INTA 0x1E0000
#define PIB_OFST_XTP 0x1E0008
/*
*Mask bit
*/
#define SAPIC_MASK_SHIFT 16
#define SAPIC_MASK (1 << SAPIC_MASK_SHIFT)
#define VLSAPIC_XTP(_v) VMX(_v, xtp)
extern void vtm_init(struct vcpu *vcpu);
extern void vtm_set_itc(struct vcpu *vcpu, uint64_t new_itc);
extern void vtm_set_itm(struct vcpu *vcpu, uint64_t val);
extern void vtm_set_itv(struct vcpu *vcpu, uint64_t val);
extern void vmx_vexirq(struct vcpu *vcpu);
extern void vhpi_detection(struct vcpu *vcpu);
extern int vlsapic_deliver_int(struct domainpre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */--- a/src/lvm.c
+++ b/src/lvm.c
@@ -31,6 +31,9 @@
/* limit for table tag-method chains (to avoid loops) */
#define MAXTAGLOOP 100
+#ifdef __GNUC__
+#define COMPUTED_GOTO 1
+#endif
/*
* If 'obj' is a string, it is tried to be interpreted as a number.
@@ -568,12 +571,63 @@ static inline int arith_mode( const TVal
ARITH_OP1_END
#endif
+#ifdef COMPUTED_GOTO
+#define OPCODE_TARGET(op) DO_OP_##op:
+#define CALL_OPCODE(op) goto *opcodes[op];
+#define OPCODE_PTR(op) [OP_##op] = &&DO_OP_##op
+#else
+#define OPCODE_TARGET(op) case OP_##op:
+#define CALL_OPCODE(op) switch (op)
+#endif
+
void luaV_execute (lua_State *L, int nexeccalls) {
LClosure *cl;
StkId base;
TValue *k;
const Instruction *pc;
+#ifdef COMPUTED_GOTO
+ static const void *opcodes[] = {
+ OPCODE_PTR(MOVE),
+ OPCODE_PTR(LOADK),
+ OPCODE_PTR(LOADBOOL),
+ OPCODE_PTR(LOADNIL),
+ OPCODE_PTR(GETUPVAL),
+ OPCODE_PTR(GETGLOBAL),
+ OPCODE_PTR(GETTABLE),
+ OPCODE_PTR(SETGLOBAL),
+ OPCODE_PTR(SETUPVAL),
+ OPCODE_PTR(SETTABLE),
+ OPCODE_PTR(NEWTABLE),
+ OPCODE_PTR(SELF),
+ OPCODE_PTR(ADD),
+ OPCODE_PTR(SUB),
+ OPCODE_PTR(MUL),
+ OPCODE_PTR(DIV),
+ OPCODE_PTR(MOD),
+ OPCODE_PTR(POW),
+ OPCODE_PTR(UNM),
+ OPCODE_PTR(NOT),
+ OPCODE_PTR(LEN),
+ OPCODE_PTR(CONCAT),
+ OPCODE_PTR(JMP),
+ OPCODE_PTR(EQ),
+ OPCODE_PTR(LT),
+ OPCODE_PTR(LE),
+ OPCODE_PTR(TEST),
+ OPCODE_PTR(TESTSET),
+ OPCODE_PTR(CALL),
+ OPCODE_PTR(TAILCALL),
+ OPCODE_PTR(RETURN),
+ OPCODE_PTR(FORLOOP),
+ OPCODE_PTR(FORPREP),
+ OPCODE_PTR(TFORLOOP),
+ OPCODE_PTR(SETLIST),
+ OPCODE_PTR(CLOSE),
+ OPCODE_PTR(CLOSURE),
+ OPCODE_PTR(VARARG)
+ };
+#endif
reentry: /* entry point */
lua_assert(isLua(L->ci));
pc = L->savedpc;
@@ -598,33 +652,33 @@ void luaV_execute (lua_State *L, int nex
lua_assert(base == L->base && L->base == L->ci->base);
lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
- switch (GET_OPCODE(i)) {
- case OP_MOVE: {
+ CALL_OPCODE(GET_OPCODE(i)) {
+ OPCODE_TARGET(MOVE) {
setobjs2s(L, ra, RB(i));
continue;
}
- case OP_LOADK: {
+ OPCODE_TARGET(LOADK) {
setobj2s(L, ra, KBx(i));
continue;
}
- case OP_LOADBOOL: {
+ OPCODE_TARGET(LOADBOOL) {
setbvalue(ra, GETARG_B(i));
if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
continue;
}
- case OP_LOADNIL: {
+ OPCODE_TARGET(LOADNIL) {
TValue *rb = RB(i);
do {
setnilvalue(rb--);
} while (rb >= ra);
continue;
}
- case OP_GETUPVAL: {
+ OPCODE_TARGET(GETUPVAL) {
int b = GETARG_B(i);
setobj2s(L, ra, cl->upvals[b]->v);
continue;
}
- case OP_GETGLOBAL: {
+ OPCODE_TARGET(GETGLOBAL) {
TValue g;
TValue *rb = KBx(i);
sethvalue(L, &g, cl->env);
@@ -632,88 +686,88 @@ void luaV_execute (lua_State *L, int nex
Protect(luaV_gettable(L, &g, rb, ra));
continue;
}
- case OP_GETTABLE: {
+ OPCODE_TARGET(GETTABLE) {
Protect(luaV_gettable(L, RB(i), RKC(i), ra));
continue;
}
- case OP_SETGLOBAL: {
+ OPCODE_TARGET(SETGLOBAL) {
TValue g;
sethvalue(L, &g, cl->env);
lua_assert(ttisstring(KBx(i)));
Protect(luaV_settable(L, &g, KBx(i), ra));
continue;
}
- case OP_SETUPVAL: {
+ OPCODE_TARGET(SETUPVAL) {
UpVal *uv = cl->upvals[GETARG_B(i)];
setobj(L, uv->v, ra);
luaC_barrier(L, uv, ra);
continue;
}
- case OP_SETTABLE: {
+ OPCODE_TARGET(SETTABLE) {
Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
continue;
}
- case OP_NEWTABLE: {
+ OPCODE_TARGET(NEWTABLE) {
int b = GETARG_B(i);
int c = GETARG_C(i);
sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
Protect(luaC_checkGC(L));
continue;
}
- case OP_SELF: {
+ OPCODE_TARGET(SELF) {
StkId rb = RB(i);
setobjs2s(L, ra+1, rb);
Protect(luaV_gettable(L, rb, RKC(i), ra));
continue;
}
- case OP_ADD: {
+ OPCODE_TARGET(ADD) {
TValue *rb = RKB(i), *rc= RKC(i);
arith_op_continue( luai_numadd, try_addint, luai_vectadd );
Protect(Arith(L, ra, rb, rc, TM_ADD)); \
continue;
}
- case OP_SUB: {
+ OPCODE_TARGET(SUB) {
TValue *rb = RKB(i), *rc= RKC(i);
arith_op_continue( luai_numsub, try_subint, luai_vectsub );
Protect(Arith(L, ra, rb, rc, TM_SUB));
continue;
}
- case OP_MUL: {
+ OPCODE_TARGET(MUL) {
TValue *rb = RKB(i), *rc= RKC(i);
arith_op_continue(luai_nummul, try_mulint, luai_vectmul);
Protect(Arith(L, ra, rb, rc, TM_MUL));
continue;
}
- case OP_DIV: {
+ OPCODE_TARGET(DIV) {
TValue *rb = RKB(i), *rc= RKC(i);
arith_op_continue(luai_numdiv, try_divint, luai_vectdiv);
Protect(Arith(L, ra, rb, rc, TM_DIV));
continue;
}
- case OP_MOD: {
+ OPCODE_TARGET(MOD) {
TValue *rb = RKB(i), *rc= RKC(i);
arith_op_continue_scalar(luai_nummod, try_modint); /* scalars only */
Protect(Arith(L, ra, rb, rc, TM_MOD));
continue;
}
- case OP_POW: {
+ OPCODE_TARGET(POW) {
TValue *rb = RKB(i), *rc= RKC(i);
arith_op_continue(luai_numpow, try_powint, luai_vectpow);
Protect(Arith(L, ra, rb, rc, TM_POW));
continue;
}
- case OP_UNM: {
+ OPCODE_TARGET(UNM) {
TValue *rb = RB(i);
arith_op1_continue(luai_numunm, try_unmint, luai_vectunm);
Protect(Arith(L, ra, rb, rb, TM_UNM));
continue;
}
- case OP_NOT: {
+ OPCODE_TARGET(NOT) {
int res = l_isfalse(RB(i)); /* next assignment may change this value */
setbvalue(ra, res);
continue;
}
- case OP_LEN: {
+ OPCODE_TARGET(LEN) {
const TValue *rb = RB(i);
switch (ttype(rb)) {
case LUA_TTABLE: {
@@ -733,18 +787,18 @@ void luaV_execute (lua_State *L, int nex
}
continue;
}
- case OP_CONCAT: {
+ OPCODE_TARGET(CONCAT) {
int b = GETARG_B(i);
int c = GETARG_C(i);
Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
setobjs2s(L, RA(i), base+b);
continue;
}
- case OP_JMP: {
+ OPCODE_TARGET(JMP) {
dojump(L, pc, GETARG_sBx(i));
continue;
}
- case OP_EQ: {
+ OPCODE_TARGET(EQ) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
Protect(
@@ -754,7 +808,7 @@ void luaV_execute (lua_State *L, int nex
pc++;
continue;
}
- case OP_LT: {
+ OPCODE_TARGET(LT) {
Protect(
if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc));
@@ -762,7 +816,7 @@ void luaV_execute (lua_State *L, int nex
pc++;
continue;
}
- case OP_LE: {
+ OPCODE_TARGET(LE) {
Protect(
if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc));
@@ -770,13 +824,13 @@ void luaV_execute (lua_State *L, int nex
pc++;
continue;
}
- case OP_TEST: {
+ OPCODE_TARGET(TEST) {
if (l_isfalse(ra) != GETARG_C(i))
dojump(L, pc, GETARG_sBx(*pc));
pc++;
continue;
}
- case OP_TESTSET: {
+ OPCODE_TARGET(TESTSET) {
TValue *rb = RB(i);
if (l_isfalse(rb) != GETARG_C(i)) {
setobjs2s(L, ra, rb);
@@ -785,7 +839,7 @@ void luaV_execute (lua_State *L, int nex
pc++;
continue;
}
- case OP_CALL: {
+ OPCODE_TARGET(CALL) {
int b = GETARG_B(i);
int nresults = GETARG_C(i) - 1;
if (b != 0) L->top = ra+b; /* else previous instruction set top */
@@ -806,7 +860,7 @@ void luaV_execute (lua_State *L, int nex
}
}
}
- case OP_TAILCALL: {
+ OPCODE_TARGET(TAILCALL) {
int b = GETARG_B(i);
if (b != 0) L->top = ra+b; /* else previous instruction set top */
L->savedpc = pc;
@@ -838,7 +892,7 @@ void luaV_execute (lua_State *L, int nex
}
}
}
- case OP_RETURN: {
+ OPCODE_TARGET(RETURN) {
int b = GETARG_B(i);
if (b != 0) L->top = ra+b-1;
if (L->openupval) luaF_close(L, base);
@@ -853,7 +907,7 @@ void luaV_execute (lua_State *L, int nex
goto reentry;
}
}
- case OP_FORLOOP: {
+ OPCODE_TARGET(FORLOOP) {
/* If start,step and limit are all integers, we don't need to check
* against overflow in the looping.
*/
@@ -881,7 +935,7 @@ void luaV_execute (lua_State *L, int nex
}
continue;
}
- case OP_FORPREP: {
+ OPCODE_TARGET(FORPREP) {
const TValue *init = ra;
const TValue *plimit = ra+1;
const TValue *pstep = ra+2;
@@ -904,7 +958,7 @@ void luaV_execute (lua_State *L, int nex
dojump(L, pc, GETARG_sBx(i));
continue;
}
- case OP_TFORLOOP: {
+ OPCODE_TARGET(TFORLOOP) {
StkId cb = ra + 3; /* call base */
setobjs2s(L, cb+2, ra+2);
setobjs2s(L, cb+1, ra+1);
@@ -920,7 +974,7 @@ void luaV_execute (lua_State *L, int nex
pc++;
continue;
}
- case OP_SETLIST: {
+ OPCODE_TARGET(SETLIST) {
int n = GETARG_B(i);
int c = GETARG_C(i);
int last;
@@ -942,11 +996,11 @@ void luaV_execute (lua_State *L, int nex
}
continue;
}
- case OP_CLOSE: {
+ OPCODE_TARGET(CLOSE) {
luaF_close(L, ra);
continue;
}
- case OP_CLOSURE: {
+ OPCODE_TARGET(CLOSURE) {
Proto *p;
Closure *ncl;
int nup, j;
@@ -966,7 +1020,7 @@ void luaV_execute (lua_State *L, int nex
Protect(luaC_checkGC(L));
continue;
}
- case OP_VARARG: {
+ OPCODE_TARGET(VARARG) {
int b = GETARG_B(i) - 1;
int j;
CallInfo *ci = L->ci;