started a new database-backed runtime from scratch

This commit is contained in:
krangelov
2021-07-30 12:08:28 +02:00
parent 155657709a
commit 8f0a1b8fee
117 changed files with 1637 additions and 41288 deletions

View File

@@ -1,241 +0,0 @@
#include "data.h"
#include "linearizer.h"
#include "pgf.h"
#include <gu/utf8.h>
typedef struct {
PgfLinFuncs* funcs;
GuBuf* parent_stack;
GuBuf* parent_current;
GuBuf* phrases;
PgfAlignmentPhrase* last_phrase;
GuStringBuf* sbuf;
size_t n_matches;
GuExn* err;
bool bind;
PgfCapitState capit;
GuPool* out_pool;
GuPool* tmp_pool;
} PgfAlignerLin;
static void
pgf_aligner_flush_phrase(PgfAlignerLin* alin)
{
size_t n_fids = gu_buf_length(alin->parent_current);
if (alin->n_matches == n_fids &&
alin->n_matches == alin->last_phrase->n_fids) {
// if the current compound word has the same parents
// as the last one then we just combine them with a space
alin->last_phrase->phrase =
gu_format_string(alin->out_pool, "%s %s",
alin->last_phrase->phrase,
gu_string_buf_freeze(alin->sbuf, alin->tmp_pool));
} else {
// push the current word to the buffer of words
PgfAlignmentPhrase* phrase =
gu_new_flex(alin->out_pool, PgfAlignmentPhrase, fids, n_fids);
phrase->phrase = gu_string_buf_freeze(alin->sbuf, alin->out_pool);
phrase->n_fids = n_fids;
for (size_t i = 0; i < n_fids; i++) {
phrase->fids[i] = gu_buf_get(alin->parent_current, int, i);
}
gu_buf_push(alin->phrases, PgfAlignmentPhrase*, phrase);
alin->last_phrase = phrase;
}
alin->n_matches = 0;
}
static void
pgf_aligner_push_parent(PgfAlignerLin* alin, int fid)
{
gu_buf_push(alin->parent_current, int, fid);
if (alin->last_phrase != NULL) {
for (size_t i = 0; i < alin->last_phrase->n_fids; i++) {
if (fid == alin->last_phrase->fids[i]) {
alin->n_matches++;
break;
}
}
}
}
static void
pgf_aligner_lzn_symbol_token(PgfLinFuncs** funcs, PgfToken tok)
{
PgfAlignerLin* alin = gu_container(funcs, PgfAlignerLin, funcs);
if (!gu_ok(alin->err)) {
return;
}
// get the tree node id that generates this token
size_t n_parents = gu_buf_length(alin->parent_stack);
int fid = gu_buf_get(alin->parent_stack, int, n_parents-1);
// how many nodes so far are involved in the current compound word
size_t n_fids = gu_buf_length(alin->parent_current);
if (alin->bind) {
// here we glue tokens
alin->bind = false;
bool found = false;
for (size_t i = 0; i < n_fids; i++) {
int current_fid = gu_buf_get(alin->parent_current, int, i);
if (fid == current_fid) {
found = true;
break;
}
}
// add the tree node id to the list of parents if it has not
// been added already.
if (!found) {
pgf_aligner_push_parent(alin, fid);
}
} else {
// here we start a new (compound) word
pgf_aligner_flush_phrase(alin);
gu_string_buf_flush(alin->sbuf);
gu_buf_flush(alin->parent_current);
pgf_aligner_push_parent(alin, fid);
if (alin->capit == PGF_CAPIT_NEXT)
alin->capit = PGF_CAPIT_NONE;
}
GuOut* out = gu_string_buf_out(alin->sbuf);
switch (alin->capit) {
case PGF_CAPIT_NONE:
gu_string_write(tok, out, alin->err);
break;
case PGF_CAPIT_FIRST: {
GuUCS c = gu_utf8_decode((const uint8_t**) &tok);
c = gu_ucs_to_upper(c);
gu_out_utf8(c, out, alin->err);
gu_string_write(tok, out, alin->err);
alin->capit = PGF_CAPIT_NONE;
break;
}
case PGF_CAPIT_ALL:
alin->capit = PGF_CAPIT_NEXT;
// continue
case PGF_CAPIT_NEXT: {
const uint8_t* p = (uint8_t*) tok;
while (*p) {
GuUCS c = gu_utf8_decode(&p);
c = gu_ucs_to_upper(c);
gu_out_utf8(c, out, alin->err);
}
break;
}
}
}
static void
pgf_aligner_lzn_begin_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString ann, PgfCId fun)
{
PgfAlignerLin* alin = gu_container(funcs, PgfAlignerLin, funcs);
gu_buf_push(alin->parent_stack, int, fid);
}
static void
pgf_aligner_lzn_end_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString ann, PgfCId fun)
{
PgfAlignerLin* alin = gu_container(funcs, PgfAlignerLin, funcs);
gu_buf_pop(alin->parent_stack, int);
}
static void
pgf_aligner_lzn_symbol_ne(PgfLinFuncs** funcs)
{
PgfAlignerLin* alin = gu_container(funcs, PgfAlignerLin, funcs);
gu_raise(alin->err, PgalinNonExist);
}
static void
pgf_aligner_lzn_symbol_bind(PgfLinFuncs** funcs)
{
PgfAlignerLin* alin = gu_container(funcs, PgfAlignerLin, funcs);
alin->bind = true;
}
static void
pgf_aligner_lzn_symbol_capit(PgfLinFuncs** funcs, PgfCapitState capit)
{
PgfAlignerLin* alin = gu_container(funcs, PgfAlignerLin, funcs);
alin->capit = capit;
}
static void
pgf_aligner_lzn_symbol_meta(PgfLinFuncs** funcs, PgfMetaId id)
{
pgf_aligner_lzn_symbol_token(funcs, "?");
}
static PgfLinFuncs pgf_file_lin_funcs = {
.symbol_token = pgf_aligner_lzn_symbol_token,
.begin_phrase = pgf_aligner_lzn_begin_phrase,
.end_phrase = pgf_aligner_lzn_end_phrase,
.symbol_ne = pgf_aligner_lzn_symbol_ne,
.symbol_bind = pgf_aligner_lzn_symbol_bind,
.symbol_capit = pgf_aligner_lzn_symbol_capit,
.symbol_meta = pgf_aligner_lzn_symbol_meta
};
GuSeq*
pgf_align_words(PgfConcr* concr, PgfExpr expr,
GuExn* err, GuPool* pool)
{
GuPool* tmp_pool = gu_local_pool();
GuEnum* cts =
pgf_lzr_concretize(concr, expr, err, tmp_pool);
if (!gu_ok(err)) {
gu_pool_free(tmp_pool);
return NULL;
}
GuBuf* phrases = gu_new_buf(PgfAlignmentPhrase*, pool);
PgfCncTree ctree = gu_next(cts, PgfCncTree, tmp_pool);
if (!gu_variant_is_null(ctree)) {
ctree = pgf_lzr_wrap_linref(ctree, tmp_pool);
PgfAlignerLin alin = {
.funcs = &pgf_file_lin_funcs,
.parent_stack = gu_new_buf(int, tmp_pool),
.parent_current = gu_new_buf(int, tmp_pool),
.phrases = phrases,
.last_phrase = NULL,
.sbuf = gu_new_string_buf(tmp_pool),
.n_matches = 0,
.err = err,
.bind = true,
.capit = PGF_CAPIT_NONE,
.out_pool = pool,
.tmp_pool = tmp_pool
};
gu_buf_push(alin.parent_stack, int, -1);
pgf_lzr_linearize(concr, ctree, 0, &alin.funcs, tmp_pool);
if (!gu_ok(err)) {
gu_pool_free(tmp_pool);
return NULL;
}
pgf_aligner_flush_phrase(&alin);
}
gu_pool_free(tmp_pool);
return gu_buf_data_seq(phrases);
}

View File

@@ -1,58 +0,0 @@
#include "data.h"
#include <gu/variant.h>
#include <gu/assert.h>
#include <math.h>
PGF_INTERNAL bool
pgf_tokens_equal(PgfTokens* t1, PgfTokens* t2)
{
size_t len1 = gu_seq_length(t1);
size_t len2 = gu_seq_length(t2);
if (len1 != len2) {
return false;
}
for (size_t i = 0; i < len1; i++) {
GuString s1 = gu_seq_get(t1, PgfToken, i);
GuString s2 = gu_seq_get(t2, PgfToken, i);
if (strcmp(s1, s2) != 0) {
return false;
}
}
return true;
}
static int
pgf_flag_cmp_fn(GuOrder* self, const void* p1, const void* p2)
{
(void) self;
return strcmp((GuString) p1, ((PgfFlag*) p2)->name);
}
PGF_INTERNAL GuOrder pgf_flag_order[1] = { { pgf_flag_cmp_fn } };
static int
pgf_abscat_cmp_fn(GuOrder* self, const void* p1, const void* p2)
{
(void) self;
return strcmp((GuString) p1, ((PgfAbsCat*) p2)->name);
}
PGF_INTERNAL GuOrder pgf_abscat_order[1] = { { pgf_abscat_cmp_fn } };
static int
pgf_absfun_cmp_fn(GuOrder* self, const void* p1, const void* p2)
{
(void) self;
return strcmp((GuString) p1, ((PgfAbsFun*) p2)->name);
}
PGF_INTERNAL GuOrder pgf_absfun_order[1] = { { pgf_absfun_cmp_fn } };
static int
pgf_concr_cmp_fn(GuOrder* self, const void* p1, const void* p2)
{
(void) self;
return strcmp((GuString) p1, ((PgfConcr*) p2)->name);
}
PGF_INTERNAL GuOrder pgf_concr_order[1] = { { pgf_concr_cmp_fn } };

View File

@@ -1,372 +0,0 @@
#ifndef PGF_DATA_H_
#define PGF_DATA_H_
#include <gu/variant.h>
#include <gu/map.h>
#include <gu/string.h>
#include <gu/seq.h>
#include <pgf/pgf.h>
typedef struct PgfCCat PgfCCat;
typedef GuSeq PgfCCats;
#define PgfCIdMap GuStringMap
typedef struct {
PgfCId name;
PgfLiteral value;
} PgfFlag;
typedef GuSeq PgfFlags;
PGF_INTERNAL_DECL extern GuOrder pgf_flag_order[1];
// PgfPatt
typedef GuVariant PgfPatt;
typedef enum {
PGF_PATT_APP,
PGF_PATT_VAR,
PGF_PATT_AS,
PGF_PATT_WILD,
PGF_PATT_LIT,
PGF_PATT_IMPL_ARG,
PGF_PATT_TILDE,
PGF_PATT_NUM_TAGS
} PgfPattTag;
typedef struct {
PgfCId ctor;
size_t n_args;
PgfPatt args[];
} PgfPattApp;
typedef struct {
PgfLiteral lit;
} PgfPattLit;
typedef struct {
PgfCId var;
} PgfPattVar;
typedef struct {
PgfCId var;
PgfPatt patt;
} PgfPattAs;
typedef char PgfPattWild;
typedef struct {
PgfPatt patt;
} PgfPattImplArg;
typedef struct {
PgfExpr expr;
} PgfPattTilde;
typedef struct {
PgfExpr body;
size_t n_patts;
PgfPatt patts[];
} PgfEquation;
typedef GuSeq PgfEquations;
typedef void *PgfFunction;
typedef struct {
PgfCId name;
PgfType* type;
int arity;
PgfEquations* defns; // maybe null
PgfExprProb ep;
PgfFunction predicate;
struct {
PgfFunction code;
union {
size_t caf_offset;
PgfFunction* con;
};
} closure;
} PgfAbsFun;
typedef GuSeq PgfAbsFuns;
PGF_INTERNAL_DECL extern GuOrder pgf_absfun_order[1];
typedef GuMap PgfMetaChildMap;
typedef struct {
PgfCId name;
PgfHypos* context;
prob_t prob;
void* predicate;
} PgfAbsCat;
typedef GuSeq PgfAbsCats;
PGF_INTERNAL_DECL extern GuOrder pgf_abscat_order[1];
typedef struct PgfEvalGates PgfEvalGates;
typedef struct {
PgfCId name;
PgfFlags* aflags;
PgfAbsFuns* funs;
PgfAbsCats* cats;
PgfAbsFun* abs_lin_fun;
PgfEvalGates* eval_gates;
} PgfAbstr;
typedef enum {
PGF_INSTR_CHECK_ARGS = 0,
PGF_INSTR_CASE = 1,
PGF_INSTR_CASE_LIT = 2,
PGF_INSTR_SAVE = 3,
PGF_INSTR_ALLOC = 4,
PGF_INSTR_PUT_CONSTR = 5,
PGF_INSTR_PUT_CLOSURE = 6,
PGF_INSTR_PUT_LIT = 7,
PGF_INSTR_SET = 8,
PGF_INSTR_SET_PAD = 9,
PGF_INSTR_PUSH_FRAME = 10,
PGF_INSTR_PUSH = 11,
PGF_INSTR_TUCK = 12,
PGF_INSTR_EVAL = 13,
PGF_INSTR_DROP = 16,
PGF_INSTR_JUMP = 17,
PGF_INSTR_FAIL = 18,
PGF_INSTR_PUSH_ACCUM = 19,
PGF_INSTR_POP_ACCUM = 20,
PGF_INSTR_ADD = 21,
} PgfInstruction;
typedef GuSeq PgfConcrs;
PGF_INTERNAL_DECL extern GuOrder pgf_concr_order[1];
struct PgfPGF {
uint16_t major_version;
uint16_t minor_version;
PgfFlags* gflags;
PgfAbstr abstract;
PgfConcrs* concretes;
GuPool* pool; // the pool in which the grammar is allocated
};
typedef struct {
PgfAbsCat *abscat;
PgfCCats* cats;
size_t n_lins;
GuString labels[];
/**< Labels for tuples. All nested tuples, records and tables
* in the GF linearization types are flattened into a single
* tuple in the corresponding PGF concrete category. This
* field holds the labels that indicate which GF field or
* parameter (or their combination) each tuple element
* represents. */
} PgfCncCat;
typedef GuSeq PgfTokens;
PGF_INTERNAL_DECL bool
pgf_tokens_equal(PgfTokens* t1, PgfTokens* t2);
typedef GuSeq PgfSymbols;
typedef struct {
PgfSymbols* form;
/**< The form of this variant as a list of tokens. */
GuStrings* prefixes;
/**< The prefixes of the following symbol that trigger this
* form. */
} PgfAlternative;
typedef struct PgfItemConts PgfItemConts;
typedef PgfCIdMap PgfPrintNames;
typedef GuStringMap PgfCncFunOverloadMap;
typedef GuMap PgfCncOverloadMap;
typedef struct PgfItem PgfItem;
typedef GuVariant PgfSymbol;
typedef enum {
PGF_SYMBOL_CAT,
PGF_SYMBOL_LIT,
PGF_SYMBOL_VAR,
PGF_SYMBOL_KS,
PGF_SYMBOL_KP,
PGF_SYMBOL_BIND,
PGF_SYMBOL_SOFT_BIND,
PGF_SYMBOL_NE,
PGF_SYMBOL_SOFT_SPACE,
PGF_SYMBOL_CAPIT,
PGF_SYMBOL_ALL_CAPIT,
} PgfSymbolTag;
typedef struct {
int d;
int r;
} PgfSymbolIdx;
typedef PgfSymbolIdx PgfSymbolCat, PgfSymbolLit, PgfSymbolVar;
typedef struct {
char token[0]; // a flexible array that contains the token
} PgfSymbolKS;
typedef struct PgfSymbolKP
/** A prefix-dependent symbol. The form that this symbol takes
* depends on the form of a prefix of the following symbol. */
{
PgfSymbols* default_form;
/**< Default form that this symbol takes if none of of the
* variant forms is triggered. */
size_t n_forms;
PgfAlternative forms[];
/**< Variant forms whose choise depends on the following
* symbol. */
} PgfSymbolKP;
typedef struct {
char nothing[0]; // Empty struct
} PgfSymbolNE;
typedef struct {
char nothing[0]; // Empty struct
} PgfSymbolBIND;
typedef struct {
char nothing[0]; // Empty struct
} PgfSymbolCAPIT;
typedef GuBuf PgfProductionIdx;
typedef struct {
PgfSymbols* syms; // -> PgfSymbol
PgfProductionIdx* idx;
} PgfSequence;
typedef GuSeq PgfSequences;
typedef struct {
PgfAbsFun* absfun;
PgfExprProb *ep;
int funid;
size_t n_lins;
PgfSequence* lins[];
} PgfCncFun;
typedef GuSeq PgfCncFuns;
struct PgfConcr {
PgfCId name;
PgfAbstr* abstr;
PgfFlags* cflags;
PgfPrintNames* printnames;
GuMap* ccats;
PgfCncFunOverloadMap* fun_indices;
PgfCncOverloadMap* coerce_idx;
PgfCncFuns* cncfuns;
PgfSequences* sequences;
PgfCIdMap* cnccats;
int total_cats;
GuPool* pool; // if the language is loaded separately then this is the pool
GuFinalizer fin; // and this is the finalizer in the pool of the whole grammar
};
// PgfProduction
typedef GuVariant PgfProduction;
typedef enum {
PGF_PRODUCTION_APPLY,
PGF_PRODUCTION_COERCE,
PGF_PRODUCTION_EXTERN
} PgfProductionTag;
typedef struct {
PgfCCat* ccat;
PgfCCats* hypos;
} PgfPArg;
typedef GuSeq PgfPArgs;
typedef struct {
PgfCncFun* fun;
PgfPArgs* args;
} PgfProductionApply;
typedef struct PgfProductionCoerce
/** A coercion. This production is a logical union of the coercions of
* another FId. This allows common subsets of productions to be
* shared. */
{
PgfCCat* coerce;
} PgfProductionCoerce;
typedef struct {
PgfExprProb *ep;
size_t n_lins;
PgfSymbols* lins[];
} PgfProductionExtern;
typedef struct {
PgfExprProb *ep;
PgfPArgs* args;
} PgfProductionMeta;
typedef GuSeq PgfProductionSeq;
typedef struct {
PgfCCat* ccat;
size_t lin_idx;
PgfProductionApply* papp;
} PgfProductionIdxEntry;
struct PgfCCat {
PgfCncCat* cnccat;
PgfCncFuns* lindefs;
PgfCncFuns* linrefs;
size_t n_synprods;
PgfProductionSeq* prods;
prob_t viterbi_prob;
int fid;
int chunk_count;
PgfItemConts* conts;
struct PgfAnswers* answers;
GuFinalizer fin[0];
};
PGF_API_DECL bool
pgf_production_is_lexical(PgfProductionApply *papp,
GuBuf* non_lexical_buf, GuPool* pool);
PGF_API_DECL void
pgf_parser_index(PgfConcr* concr,
PgfCCat* ccat, PgfProduction prod,
bool is_lexical,
GuPool *pool);
PGF_API_DECL void
pgf_lzr_index(PgfConcr* concr,
PgfCCat* ccat, PgfProduction prod,
bool is_lexical,
GuPool *pool);
#endif

View File

@@ -1,513 +0,0 @@
#include "pgf/pgf.h"
#include "pgf/data.h"
#include "pgf/reasoner.h"
#include <stdlib.h>
#define PGF_ARGS_DELTA 5
static inline PgfClosure*
pgf_mk_pap(PgfReasoner* rs, PgfClosure* fun,
size_t n_args, PgfClosure** args)
{
if (n_args > 0) {
PgfValuePAP* val = gu_new_flex(rs->pool, PgfValuePAP, args, n_args);
val->header.code = rs->eval_gates->evaluate_value_pap;
val->fun = fun;
val->n_args = n_args*sizeof(PgfClosure*);
for (size_t i = 0; i < n_args; i++) {
val->args[i] = args[i];
}
return &val->header;
}
return fun;
}
PGF_INTERNAL PgfClosure*
pgf_evaluate_expr_thunk(PgfReasoner* rs, PgfExprThunk* thunk)
{
PgfEnv* env = thunk->env;
PgfExpr expr = thunk->expr;
size_t n_args = 0;
PgfClosure** args = NULL;
PgfClosure* res = NULL;
repeat:;
GuVariantInfo ei = gu_variant_open(expr);
switch (ei.tag) {
case PGF_EXPR_ABS: {
PgfExprAbs* eabs = ei.data;
if (n_args > 0) {
PgfEnv* new_env = gu_new(PgfEnv, rs->pool);
new_env->next = env;
new_env->closure = args[--n_args];
env = new_env;
expr = eabs->body;
goto repeat;
} else {
thunk->header.code = rs->eval_gates->evaluate_value_lambda;
thunk->expr = eabs->body;
res = &thunk->header;
}
break;
}
case PGF_EXPR_APP: {
PgfExprApp* eapp = ei.data;
PgfExprThunk* thunk =
gu_new(PgfExprThunk, rs->pool);
thunk->header.code = rs->eval_gates->evaluate_expr_thunk;
thunk->env = env;
thunk->expr = eapp->arg;
if (n_args % PGF_ARGS_DELTA == 0) {
args = realloc(args, n_args + PGF_ARGS_DELTA);
}
args[n_args++] = &thunk->header;
expr = eapp->fun;
goto repeat;
}
case PGF_EXPR_LIT: {
PgfExprLit* elit = ei.data;
PgfValueLit* val = (PgfValueLit*) thunk;
val->header.code = rs->eval_gates->evaluate_value_lit;
val->lit = elit->lit;
res = &val->header;
break;
}
case PGF_EXPR_META: {
PgfExprMeta* emeta = ei.data;
PgfValueMeta* val =
gu_new(PgfValueMeta, rs->pool);
val->header.code = rs->eval_gates->evaluate_meta;
val->env = env;
val->id = emeta->id;
res = pgf_mk_pap(rs, &val->header, n_args, args);
break;
}
case PGF_EXPR_FUN: {
PgfExprFun* efun = ei.data;
PgfAbsFun* absfun =
gu_seq_binsearch(rs->abstract->funs, pgf_absfun_order, PgfAbsFun, efun->fun);
gu_assert(absfun != NULL);
if (absfun->closure.code != NULL) {
res = pgf_mk_pap(rs, (PgfClosure*) &absfun->closure, n_args, args);
} else {
size_t arity = absfun->arity;
if (n_args >= arity) {
PgfValue* val = gu_new_flex(rs->pool, PgfValue, args, n_args);
val->header.code = rs->eval_gates->evaluate_value;
val->con = (PgfClosure*) &absfun->closure;
for (size_t i = 0; i < n_args; i++) {
val->args[i] = args[--n_args];
}
res = &val->header;
} else {
PgfExprThunk* lambda = gu_new(PgfExprThunk, rs->pool);
lambda->header.code = rs->eval_gates->evaluate_value_lambda;
lambda->env = NULL;
res = pgf_mk_pap(rs, &lambda->header, n_args, args);
for (size_t i = 0; i < arity; i++) {
PgfExpr new_expr, arg;
PgfExprVar *evar =
gu_new_variant(PGF_EXPR_VAR,
PgfExprVar,
&arg, rs->pool);
evar->var = arity-i-1;
PgfExprApp *eapp =
gu_new_variant(PGF_EXPR_APP,
PgfExprApp,
&new_expr, rs->pool);
eapp->fun = expr;
eapp->arg = arg;
expr = new_expr;
}
for (size_t i = 0; i < arity-1; i++) {
PgfExpr new_expr;
PgfExprAbs *eabs =
gu_new_variant(PGF_EXPR_ABS,
PgfExprAbs,
&new_expr, rs->pool);
eabs->bind_type = PGF_BIND_TYPE_EXPLICIT;
eabs->id = "_";
eabs->body = expr;
expr = new_expr;
}
lambda->expr = expr;
}
}
break;
}
case PGF_EXPR_VAR: {
PgfExprVar* evar = ei.data;
PgfEnv* tmp_env = env;
size_t i = evar->var;
while (i > 0) {
tmp_env = tmp_env->next;
if (tmp_env == NULL) {
GuExnData* err_data = gu_raise(rs->err, PgfExn);
if (err_data) {
err_data->data = "invalid de Bruijn index";
}
return NULL;
}
i--;
}
res = pgf_mk_pap(rs, tmp_env->closure, n_args, args);
break;
}
case PGF_EXPR_TYPED: {
PgfExprTyped* etyped = ei.data;
expr = etyped->expr;
goto repeat;
}
case PGF_EXPR_IMPL_ARG: {
PgfExprImplArg* eimpl = ei.data;
expr = eimpl->expr;
goto repeat;
}
default:
gu_impossible();
}
free(args);
return res;
}
PGF_INTERNAL PgfClosure*
pgf_evaluate_lambda_application(PgfReasoner* rs, PgfExprThunk* lambda,
PgfClosure* arg)
{
PgfEnv* new_env = gu_new(PgfEnv, rs->pool);
new_env->next = lambda->env;
new_env->closure = arg;
PgfExprThunk* thunk = gu_new(PgfExprThunk, rs->pool);
thunk->header.code = rs->eval_gates->evaluate_expr_thunk;
thunk->env = new_env;
thunk->expr = lambda->expr;
return pgf_evaluate_expr_thunk(rs, thunk);
}
static PgfExpr
pgf_value2expr(PgfReasoner* rs, int level, PgfClosure* clos)
{
clos = rs->eval_gates->enter(rs, clos);
if (clos == NULL)
return gu_null_variant;
PgfExpr expr = gu_null_variant;
size_t n_args = 0;
PgfClosure** args;
if (clos->code == rs->eval_gates->evaluate_value) {
PgfValue* val = (PgfValue*) clos;
PgfAbsFun* absfun = gu_container(val->con, PgfAbsFun, closure);
expr = absfun->ep.expr;
n_args = gu_seq_length(absfun->type->hypos);
args = val->args;
} else if (clos->code == rs->eval_gates->evaluate_value_lit) {
PgfValueLit* val = (PgfValueLit*) clos;
PgfExprLit *elit =
gu_new_variant(PGF_EXPR_LIT,
PgfExprLit,
&expr, rs->out_pool);
GuVariantInfo i = gu_variant_open(val->lit);
switch (i.tag) {
case PGF_LITERAL_STR: {
PgfLiteralStr* lstr = i.data;
PgfLiteralStr* new_lstr =
gu_new_flex_variant(PGF_LITERAL_STR,
PgfLiteralStr,
val, strlen(lstr->val)+1,
&elit->lit, rs->out_pool);
strcpy(new_lstr->val, lstr->val);
break;
}
case PGF_LITERAL_INT: {
PgfLiteralInt* lint = i.data;
PgfLiteralInt* new_lint =
gu_new_variant(PGF_LITERAL_INT,
PgfLiteralInt,
&elit->lit, rs->out_pool);
new_lint->val = lint->val;
break;
}
case PGF_LITERAL_FLT: {
PgfLiteralFlt* lflt = i.data;
PgfLiteralFlt* new_lflt =
gu_new_variant(PGF_LITERAL_FLT,
PgfLiteralFlt,
&elit->lit, rs->out_pool);
new_lflt->val = lflt->val;
break;
}
default:
gu_impossible();
}
} else if (clos->code == rs->eval_gates->evaluate_value_pap) {
PgfValuePAP *pap = (PgfValuePAP*) clos;
PgfValueGen* gen =
gu_new(PgfValueGen, rs->pool);
gen->header.code = rs->eval_gates->evaluate_gen;
gen->level = level;
size_t n_args = pap->n_args/sizeof(PgfClosure*);
PgfValuePAP* new_pap = gu_new_flex(rs->pool, PgfValuePAP, args, n_args+1);
new_pap->header.code = rs->eval_gates->evaluate_value_pap;
new_pap->fun = pap->fun;
new_pap->n_args = pap->n_args+sizeof(PgfClosure*);
new_pap->args[0] = &gen->header;
for (size_t i = 0; i < n_args; i++) {
new_pap->args[i+1] = pap->args[i];
}
PgfExprAbs *eabs =
gu_new_variant(PGF_EXPR_ABS,
PgfExprAbs,
&expr, rs->out_pool);
eabs->bind_type = PGF_BIND_TYPE_EXPLICIT;
eabs->id = gu_format_string(rs->out_pool, "v%d", level);
eabs->body = pgf_value2expr(rs, level+1, &new_pap->header);
} else if (clos->code == rs->eval_gates->evaluate_value_const) {
PgfValuePAP* val = (PgfValuePAP*) clos;
if (val->fun->code == rs->eval_gates->evaluate_meta) {
PgfValueMeta* fun = (PgfValueMeta*) val->fun;
PgfExprMeta *emeta =
gu_new_variant(PGF_EXPR_META,
PgfExprMeta,
&expr, rs->out_pool);
emeta->id = fun->id;
} else if (val->fun->code == rs->eval_gates->evaluate_gen) {
PgfValueGen* fun = (PgfValueGen*) val->fun;
PgfExprVar *evar =
gu_new_variant(PGF_EXPR_VAR,
PgfExprVar,
&expr, rs->out_pool);
evar->var = level - fun->level - 1;
} else if (val->fun->code == rs->eval_gates->evaluate_sum) {
PgfValueSum* sum = (PgfValueSum*) val->fun;
PgfExpr e1,e2;
PgfExprFun *efun =
gu_new_flex_variant(PGF_EXPR_FUN,
PgfExprFun,
fun, 2,
&e1, rs->out_pool);
strcpy(efun->fun, "+");
PgfExprLit *elit =
gu_new_variant(PGF_EXPR_LIT,
PgfExprLit,
&e2, rs->out_pool);
elit->lit = sum->lit;
PgfExprApp* eapp =
gu_new_variant(PGF_EXPR_APP,
PgfExprApp,
&expr, rs->out_pool);
eapp->fun = e1;
eapp->arg = e2;
size_t n_consts = gu_buf_length(sum->consts);
for (size_t i = 0; i < n_consts; i++) {
PgfClosure* con =
gu_buf_get(sum->consts, PgfClosure*, i);
PgfExpr fun = expr;
PgfExpr arg =
pgf_value2expr(rs, level, con);
if (gu_variant_is_null(arg))
return gu_null_variant;
PgfExprApp* e =
gu_new_variant(PGF_EXPR_APP,
PgfExprApp,
&expr, rs->out_pool);
e->fun = fun;
e->arg = arg;
}
} else {
PgfAbsFun* absfun = gu_container(val->fun, PgfAbsFun, closure);
expr = absfun->ep.expr;
}
n_args = val->n_args/sizeof(PgfClosure*);
args = val->args;
} else {
gu_impossible();
}
for (size_t i = 0; i < n_args; i++) {
PgfExpr fun = expr;
PgfExpr arg =
pgf_value2expr(rs, level, args[i]);
if (gu_variant_is_null(arg))
return gu_null_variant;
PgfExprApp* e =
gu_new_variant(PGF_EXPR_APP,
PgfExprApp,
&expr, rs->out_pool);
e->fun = fun;
e->arg = arg;
}
return expr;
}
PGF_API PgfExpr
pgf_compute(PgfPGF* pgf, PgfExpr expr, GuExn* err, GuPool* pool, GuPool* out_pool)
{
PgfReasoner* rs =
pgf_new_reasoner(pgf, err, pool, out_pool);
PgfExprThunk* thunk =
gu_new(PgfExprThunk, pool);
thunk->header.code = rs->eval_gates->evaluate_expr_thunk;
thunk->env = NULL;
thunk->expr = expr;
return pgf_value2expr(rs, 0, &thunk->header);
}
PGF_INTERNAL void
pgf_evaluate_accum_init_int(PgfReasoner* rs,
PgfEvalAccum* accum, int val)
{
PgfLiteralInt *lit_int =
gu_new_variant(PGF_LITERAL_INT,
PgfLiteralInt,
&accum->lit,
rs->pool);
lit_int->val = val;
accum->consts = NULL;
}
PGF_INTERNAL void
pgf_evaluate_accum_init_str(PgfReasoner* rs,
PgfEvalAccum* accum, GuString val)
{
if (val == NULL)
val = "";
PgfLiteralStr *lit_str =
gu_new_flex_variant(PGF_LITERAL_STR,
PgfLiteralStr,
val, strlen(val)+1,
&accum->lit, rs->pool);
strcpy((char*) lit_str->val, (char*) val);
accum->consts = NULL;
}
PGF_INTERNAL void
pgf_evaluate_accum_init_flt(PgfReasoner* rs,
PgfEvalAccum* accum, float val)
{
PgfLiteralFlt *lit_flt =
gu_new_variant(PGF_LITERAL_FLT,
PgfLiteralFlt,
&accum->lit,
rs->pool);
lit_flt->val = val;
accum->enter_stack_ptr = rs->enter_stack_ptr;
rs->enter_stack_ptr = ((char*)accum)-sizeof(char*)*2;
accum->consts = NULL;
}
static void
pgf_evaluate_accum_add_helper(PgfEvalAccum* accum, PgfLiteral lit)
{
GuVariantInfo ei = gu_variant_open(lit);
switch (ei.tag) {
case PGF_LITERAL_INT: {
PgfLiteralInt* lint = ei.data;
((PgfLiteralInt*)gu_variant_data(accum->lit))->val += lint->val;
break;
}
case PGF_LITERAL_STR: {
PgfLiteralStr* lstr = ei.data;
break;
}
case PGF_LITERAL_FLT: {
PgfLiteralFlt* lflt = ei.data;
((PgfLiteralFlt*)gu_variant_data(accum->lit))->val += lflt->val;
break;
}
}
}
PGF_INTERNAL void
pgf_evaluate_accum_add(PgfReasoner* rs,
PgfEvalAccum* accum, PgfClosure* closure)
{
if (closure->code == rs->eval_gates->evaluate_value_lit) {
PgfValueLit* val = (PgfValueLit*) closure;
pgf_evaluate_accum_add_helper(accum, val->lit);
} else if (closure->code == rs->eval_gates->evaluate_value_const) {
if (accum->consts == NULL)
accum->consts = gu_new_buf(PgfClosure*, rs->pool);
PgfValuePAP* pap = (PgfValuePAP*) closure;
if (pap->fun->code == rs->eval_gates->evaluate_sum) {
PgfValueSum* val = (PgfValueSum*) ((PgfValuePAP*) closure)->fun;
pgf_evaluate_accum_add_helper(accum, val->lit);
size_t n_consts = gu_buf_length(val->consts);
for (size_t i = 0; i < n_consts; i++) {
PgfClosure* clos = gu_buf_get(val->consts, PgfClosure*, i);
gu_buf_push(accum->consts, PgfClosure*, clos);
}
} else {
gu_buf_push(accum->consts, PgfClosure*, closure);
}
} else {
gu_impossible();
}
}
PGF_INTERNAL PgfClosure*
pgf_evaluate_accum_done(PgfReasoner* rs, PgfEvalAccum* accum)
{
rs->enter_stack_ptr = accum->enter_stack_ptr;
if (accum->consts == NULL) {
PgfValueLit* val = gu_new(PgfValueLit, rs->pool);
val->header.code = rs->eval_gates->evaluate_value_lit;
val->lit = accum->lit;
return &val->header;
} else {
PgfValueSum* val = gu_new(PgfValueSum, rs->pool);
val->header.code = rs->eval_gates->evaluate_sum;
val->lit = accum->lit;
val->consts = accum->consts;
return &val->header;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,245 +0,0 @@
#ifndef EXPR_H_
#define EXPR_H_
#include <gu/in.h>
#include <gu/out.h>
#include <gu/variant.h>
#include <gu/seq.h>
/// Abstract syntax trees
/// @file
/// An abstract syntax tree
typedef GuVariant PgfExpr;
typedef struct PgfHypo PgfHypo;
typedef struct PgfType PgfType;
typedef int PgfMetaId;
typedef enum {
PGF_BIND_TYPE_EXPLICIT,
PGF_BIND_TYPE_IMPLICIT
} PgfBindType;
// PgfLiteral
typedef GuVariant PgfLiteral;
typedef enum {
PGF_LITERAL_STR,
PGF_LITERAL_INT,
PGF_LITERAL_FLT,
PGF_LITERAL_NUM_TAGS
} PgfLiteralTag;
typedef struct {
char val[0]; // a flexible array that contains the value
} PgfLiteralStr;
typedef struct {
int val;
} PgfLiteralInt;
typedef struct {
double val;
} PgfLiteralFlt;
struct PgfHypo {
PgfBindType bind_type;
PgfCId cid;
/**< Locally scoped name for the parameter if dependent types
* are used. "_" for normal parameters. */
PgfType* type;
};
typedef GuSeq PgfHypos;
struct PgfType {
PgfHypos* hypos;
PgfCId cid; /// XXX: resolve to PgfCat*?
size_t n_exprs;
PgfExpr exprs[];
};
typedef enum {
PGF_EXPR_ABS,
PGF_EXPR_APP,
PGF_EXPR_LIT,
PGF_EXPR_META,
PGF_EXPR_FUN,
PGF_EXPR_VAR,
PGF_EXPR_TYPED,
PGF_EXPR_IMPL_ARG,
PGF_EXPR_NUM_TAGS
} PgfExprTag;
typedef struct {
PgfBindType bind_type;
PgfCId id;
PgfExpr body;
} PgfExprAbs;
typedef struct {
PgfExpr fun;
PgfExpr arg;
} PgfExprApp;
typedef struct {
PgfLiteral lit;
} PgfExprLit;
typedef struct {
PgfMetaId id;
} PgfExprMeta;
typedef struct {
char fun[0];
} PgfExprFun;
typedef struct {
int var;
} PgfExprVar;
/**< A variable. The value is a de Bruijn index to the environment,
* beginning from the innermost variable. */
typedef struct {
PgfExpr expr;
PgfType* type;
} PgfExprTyped;
typedef struct {
PgfExpr expr;
} PgfExprImplArg;
typedef float prob_t;
typedef struct {
prob_t prob;
PgfExpr expr;
} PgfExprProb;
typedef struct PgfApplication PgfApplication;
struct PgfApplication {
PgfExpr efun;
PgfCId fun;
int n_args;
PgfExpr args[];
};
PGF_API_DECL PgfApplication*
pgf_expr_unapply(PgfExpr expr, GuPool* pool);
PGF_API_DECL PgfApplication*
pgf_expr_unapply_ex(PgfExpr expr, GuPool* pool);
PGF_API_DECL PgfExpr
pgf_expr_apply(PgfApplication*, GuPool* pool);
PGF_API_DECL PgfExpr
pgf_expr_abs(PgfBindType bind_type, PgfCId id, PgfExpr body, GuPool* pool);
PGF_API_DECL PgfExprAbs*
pgf_expr_unabs(PgfExpr expr);
PGF_API_DECL PgfExpr
pgf_expr_string(GuString, GuPool* pool);
PGF_API_DECL PgfExpr
pgf_expr_int(int val, GuPool* pool);
PGF_API_DECL PgfExpr
pgf_expr_float(double val, GuPool* pool);
PGF_API_DECL void*
pgf_expr_unlit(PgfExpr expr, int lit_tag);
PGF_API_DECL PgfExpr
pgf_expr_meta(int id, GuPool* pool);
PGF_API_DECL PgfExprMeta*
pgf_expr_unmeta(PgfExpr expr);
PGF_API_DECL PgfExpr
pgf_read_expr(GuIn* in, GuPool* pool, GuPool* tmp_pool, GuExn* err);
PGF_API_DECL PgfType*
pgf_read_type(GuIn* in, GuPool* pool, GuPool* tmp_pool, GuExn* err);
PGF_API_DECL bool
pgf_literal_eq(PgfLiteral lit1, PgfLiteral lit2);
PGF_API_DECL int
pgf_expr_eq(PgfExpr e1, PgfExpr e2);
PGF_API_DECL bool
pgf_type_eq(PgfType* t1, PgfType* t2);
PGF_API_DECL GuHash
pgf_literal_hash(GuHash h, PgfLiteral lit);
PGF_API_DECL GuHash
pgf_expr_hash(GuHash h, PgfExpr e);
PGF_API_DECL size_t
pgf_expr_size(PgfExpr expr);
PGF_API_DECL GuSeq*
pgf_expr_functions(PgfExpr expr, GuPool* pool);
PGF_API_DECL PgfExpr
pgf_expr_substitute(PgfExpr expr, GuSeq* meta_values, GuPool* pool);
PGF_API_DECL PgfType*
pgf_type_substitute(PgfType* type, GuSeq* meta_values, GuPool* pool);
typedef struct PgfPrintContext PgfPrintContext;
struct PgfPrintContext {
PgfCId name;
PgfPrintContext* next;
};
PGF_API_DECL void
pgf_print_cid(PgfCId id, GuOut* out, GuExn* err);
PGF_API_DECL void
pgf_print_literal(PgfLiteral lit, GuOut* out, GuExn* err);
PGF_API_DECL void
pgf_print_expr(PgfExpr expr, PgfPrintContext* ctxt, int prec,
GuOut* out, GuExn* err);
PGF_API_DECL PgfPrintContext*
pgf_print_hypo(PgfHypo *hypo, PgfPrintContext* ctxt, int prec,
GuOut* out, GuExn *err);
PGF_API_DECL void
pgf_print_type(PgfType *type, PgfPrintContext* ctxt, int prec,
GuOut* out, GuExn *err);
PGF_API_DECL void
pgf_print_context(PgfHypos *hypos, PgfPrintContext* ctxt,
GuOut *out, GuExn *err);
PGF_API PgfLiteral
pgf_clone_literal(PgfLiteral lit, GuPool* pool);
PGF_API PgfExpr
pgf_clone_expr(PgfExpr expr, GuPool* pool);
PGF_API PgfType*
pgf_clone_type(PgfType* type, GuPool* pool);
PGF_API_DECL prob_t
pgf_compute_tree_probability(PgfPGF *gr, PgfExpr expr);
#endif /* EXPR_H_ */

View File

@@ -1,415 +0,0 @@
#include "data.h"
#include "graphviz.h"
#include "linearizer.h"
PgfGraphvizOptions pgf_default_graphviz_options[1] =
{ {0, 0, 0, 1, NULL, NULL, NULL, NULL, NULL, NULL} } ;
static int
pgf_graphviz_abstract_tree_(PgfPGF* pgf, PgfExpr expr, int *pid,
PgfGraphvizOptions* opts,
GuOut* out, GuExn* err)
{
int id = -1;
GuVariantInfo ei = gu_variant_open(expr);
switch (ei.tag) {
case PGF_EXPR_ABS:
gu_impossible();
break;
case PGF_EXPR_APP: {
PgfExprApp* app = ei.data;
id = pgf_graphviz_abstract_tree_(pgf, app->fun, pid, opts, out, err);
int arg_id = pgf_graphviz_abstract_tree_(pgf, app->arg, pid, opts, out, err);
gu_printf(out, err, "n%d -- n%d", id, arg_id);
if (opts->nodeEdgeStyle != NULL && *opts->nodeEdgeStyle && opts->nodeColor != NULL && *opts->nodeColor)
gu_printf(out, err, " [style = \"%s\", color = \"%s\"]", opts->nodeEdgeStyle, opts->nodeColor);
else if (opts->nodeEdgeStyle != NULL && *opts->nodeEdgeStyle)
gu_printf(out, err, " [style = \"%s\"]", opts->nodeEdgeStyle);
else if (opts->nodeColor != NULL && *opts->nodeColor)
gu_printf(out, err, " [color = \"%s\"]", opts->nodeColor);
gu_printf(out, err, "\n", id, arg_id);
break;
}
case PGF_EXPR_LIT: {
PgfExprLit* lit = ei.data;
id = (*pid)++;
gu_printf(out, err, "n%d[label = \"", id);
GuVariantInfo ei = gu_variant_open(lit->lit);
switch (ei.tag) {
case PGF_LITERAL_STR: {
PgfLiteralStr* lit = ei.data;
gu_puts("\\\"", out, err);
gu_string_write(lit->val, out, err);
gu_puts("\\\"", out, err);
break;
}
case PGF_LITERAL_INT: {
PgfLiteralInt* lit = ei.data;
gu_printf(out, err, "%d", lit->val);
break;
}
case PGF_LITERAL_FLT: {
PgfLiteralFlt* lit = ei.data;
gu_printf(out, err, "%lf", lit->val);
break;
}
default:
gu_impossible();
}
gu_puts("\", style = \"solid\", shape = \"plaintext\"]\n", out, err);
break;
}
case PGF_EXPR_META:
id = (*pid)++;
gu_printf(out, err, "n%d[label = \"?\", style = \"solid\", shape = \"plaintext\"]\n", id);
break;
case PGF_EXPR_FUN: {
PgfExprFun* fun = ei.data;
id = (*pid)++;
if (opts->noFun && opts->noCat) {
gu_printf(out, err, "n%d[shape = \"point\"]\n", id);
} else {
gu_printf(out, err, "n%d[label = \"", id);
PgfType* ty = (opts->noCat) ? NULL : pgf_function_type(pgf, fun->fun);
if (!opts->noFun)
gu_string_write(fun->fun, out, err);
if (!opts->noFun && ty != NULL)
gu_puts(" : ", out,err);
if (ty != NULL)
gu_string_write(ty->cid, out, err);
gu_puts("\", shape = \"plaintext\", style = \"solid\"", out, err);
if (opts->nodeColor != NULL && *opts->nodeColor)
gu_printf(out, err, ", fontcolor = \"%s\"", opts->nodeColor);
if (opts->nodeFont != NULL && *opts->nodeFont)
gu_printf(out, err, ", fontname = \"%s\"", opts->nodeFont);
gu_puts("]\n", out, err);
}
break;
}
case PGF_EXPR_VAR:
gu_impossible();
break;
case PGF_EXPR_TYPED: {
PgfExprTyped* typed = ei.data;
id = pgf_graphviz_abstract_tree_(pgf, typed->expr, pid, opts, out, err);
break;
}
case PGF_EXPR_IMPL_ARG: {
PgfExprImplArg* implarg = ei.data;
id = pgf_graphviz_abstract_tree_(pgf, implarg->expr, pid, opts, out, err);
break;
}
default:
gu_impossible();
}
return id;
}
PGF_API void
pgf_graphviz_abstract_tree(PgfPGF* pgf, PgfExpr expr, PgfGraphvizOptions* opts, GuOut* out, GuExn* err)
{
int id = 0;
gu_puts("graph {\n", out, err);
pgf_graphviz_abstract_tree_(pgf, expr, &id, opts, out, err);
gu_puts("}", out, err);
}
typedef struct PgfParseNode PgfParseNode;
struct PgfParseNode {
int id;
PgfParseNode* parent;
GuString fun;
GuString label;
};
typedef struct {
PgfLinFuncs* funcs;
GuPool* pool;
GuOut* out;
GuExn* err;
PgfParseNode* parent;
size_t level;
GuBuf* internals;
GuBuf* leaves;
} PgfBracketLznState;
static void
pgf_bracket_lzn_symbol_token(PgfLinFuncs** funcs, PgfToken tok)
{
PgfBracketLznState* state = gu_container(funcs, PgfBracketLznState, funcs);
PgfParseNode* node = gu_new(PgfParseNode, state->pool);
node->id = 100000 + gu_buf_length(state->leaves);
node->parent = state->parent;
node->fun = NULL;
node->label = tok;
gu_buf_push(state->leaves, PgfParseNode*, node);
}
static void
pgf_bracket_lzn_begin_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString ann, PgfCId fun)
{
PgfBracketLznState* state = gu_container(funcs, PgfBracketLznState, funcs);
if (strcmp(cat, "_") == 0)
return;
state->level++;
GuBuf* level;
if (state->level < gu_buf_length(state->internals))
level = gu_buf_get(state->internals, GuBuf*, state->level);
else {
level = gu_new_buf(PgfParseNode*, state->pool);
gu_buf_push(state->internals, GuBuf*, level);
}
size_t len = gu_buf_length(level);
for (size_t i = 0; i < len; i++) {
PgfParseNode* node = gu_buf_get(level, PgfParseNode*, i);
if (node->id == fid) {
state->parent = node;
return;
}
}
PgfParseNode* node = gu_new(PgfParseNode, state->pool);
node->id = fid;
node->parent = state->parent;
node->fun = fun;
node->label = cat;
gu_buf_push(level, PgfParseNode*, node);
state->parent = node;
}
static void
pgf_bracket_lzn_end_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString ann, PgfCId fun)
{
PgfBracketLznState* state = gu_container(funcs, PgfBracketLznState, funcs);
if (strcmp(cat, "_") == 0)
return;
state->level--;
state->parent = state->parent->parent;
}
static void
pgf_bracket_lzn_symbol_meta(PgfLinFuncs** funcs, PgfMetaId meta_id)
{
PgfBracketLznState* state = gu_container(funcs, PgfBracketLznState, funcs);
PgfParseNode* node = gu_new(PgfParseNode, state->pool);
node->id = 100000 + gu_buf_length(state->leaves);
node->parent = state->parent;
node->fun = NULL;
node->label = "?";
gu_buf_push(state->leaves, PgfParseNode*, node);
}
static PgfLinFuncs pgf_bracket_lin_funcs = {
.symbol_token = pgf_bracket_lzn_symbol_token,
.begin_phrase = pgf_bracket_lzn_begin_phrase,
.end_phrase = pgf_bracket_lzn_end_phrase,
.symbol_ne = NULL,
.symbol_bind = NULL,
.symbol_capit = NULL,
.symbol_meta = pgf_bracket_lzn_symbol_meta
};
static void
pgf_graphviz_parse_level(GuBuf* level, PgfGraphvizOptions* opts, GuOut* out, GuExn* err)
{
gu_puts("\n subgraph {rank=same;\n", out, err);
size_t len = gu_buf_length(level);
if (len > 1)
gu_puts(" edge[style=invis]\n", out, err);
for (size_t i = 0; i < len; i++) {
PgfParseNode* node = gu_buf_get(level, PgfParseNode*, i);
if (node->fun != NULL) {
gu_printf(out, err, " n%d[label=\"", node->id);
if (!opts->noFun)
gu_string_write(node->fun, out, err);
if (!opts->noFun && !opts->noCat)
gu_puts(" : ", out, err);
if (!opts->noCat)
gu_string_write(node->label, out, err);
gu_puts("\"", out, err);
if (opts->nodeColor != NULL && *opts->nodeColor)
gu_printf(out, err, ", fontcolor = \"%s\"", opts->nodeColor);
if (opts->nodeFont != NULL && *opts->nodeFont)
gu_printf(out, err, ", fontname = \"%s\"", opts->nodeFont);
gu_puts("]\n", out, err);
} else {
if (opts->noLeaves)
gu_printf(out, err, " n%d[label=\"\"]\n", node->id);
else {
gu_printf(out, err, " n%d[label=\"%s\"", node->id, node->label);
if (opts->leafColor != NULL && *opts->leafColor)
gu_printf(out, err, ", fontcolor = \"%s\"", opts->leafColor);
if (opts->leafFont != NULL && *opts->leafFont)
gu_printf(out, err, ", fontname = \"%s\"", opts->leafFont);
gu_puts("]\n", out, err);
}
}
}
if (len > 1) {
for (size_t i = 0; i < len; i++) {
PgfParseNode* node = gu_buf_get(level, PgfParseNode*, i);
gu_puts((i == 0) ? " " : " -- ", out, err);
gu_printf(out, err, "n%d", node->id);
}
gu_puts("\n", out, err);
}
gu_puts(" }\n", out, err);
for (size_t i = 0; i < len; i++) {
PgfParseNode* node = gu_buf_get(level, PgfParseNode*, i);
if (node->parent != NULL) {
gu_printf(out, err, " n%d -- n%d", node->parent->id, node->id);
GuString edgeStyle, color;
if (node->fun == NULL) {
edgeStyle = opts->leafEdgeStyle;
color = opts->leafColor;
} else {
edgeStyle = opts->nodeEdgeStyle;
color = opts->nodeColor;
}
if (edgeStyle != NULL && *edgeStyle && color != NULL && *color)
gu_printf(out, err, " [style = \"%s\", color = \"%s\"]", edgeStyle, color);
else if (edgeStyle != NULL && *edgeStyle)
gu_printf(out, err, " [style = \"%s\"]", edgeStyle);
else if (color != NULL && *color)
gu_printf(out, err, " [color = \"%s\"]", color);
gu_putc('\n', out, err);
}
}
}
PGF_API void
pgf_graphviz_parse_tree(PgfConcr* concr, PgfExpr expr, PgfGraphvizOptions* opts, GuOut* out, GuExn* err)
{
GuPool* tmp_pool = gu_local_pool();
GuEnum* cts =
pgf_lzr_concretize(concr, expr, err, tmp_pool);
if (!gu_ok(err)) {
gu_pool_free(tmp_pool);
return;
}
PgfCncTree ctree = gu_next(cts, PgfCncTree, tmp_pool);
if (gu_variant_is_null(ctree)) {
gu_pool_free(tmp_pool);
return;
}
gu_puts("graph {\n", out, err);
gu_puts(" node[shape=plaintext]\n", out, err);
PgfBracketLznState state;
state.funcs = &pgf_bracket_lin_funcs;
state.pool = tmp_pool;
state.out = out;
state.err = err;
state.parent = NULL;
state.level = -1;
state.internals = gu_new_buf(GuBuf*, tmp_pool);
state.leaves = gu_new_buf(PgfParseNode*, tmp_pool);
pgf_lzr_linearize(concr, ctree, 0, &state.funcs, tmp_pool);
size_t len = gu_buf_length(state.internals);
for (size_t i = 0; i < len; i++) {
GuBuf* level = gu_buf_get(state.internals, GuBuf*, i);
pgf_graphviz_parse_level(level, opts, out, err);
}
pgf_graphviz_parse_level(state.leaves, opts, out, err);
gu_puts("}", out, err);
gu_pool_free(tmp_pool);
}
PGF_API_DECL void
pgf_graphviz_word_alignment(PgfConcr** concrs, size_t n_concrs, PgfExpr expr, PgfGraphvizOptions* opts, GuOut* out, GuExn* err)
{
GuPool* tmp_pool = gu_local_pool();
gu_puts("digraph {\n", out, err);
gu_puts("rankdir=LR ;\n", out, err);
gu_puts("node [shape = record", out, err);
if (opts->leafFont != NULL && *opts->leafFont)
gu_printf(out, err, ", fontname = \"%s\"", opts->leafFont);
if (opts->leafColor != NULL && *opts->leafColor)
gu_printf(out, err, ", fontcolor = \"%s\"", opts->leafColor);
gu_puts("] ;\n\n", out, err);
if (opts->leafEdgeStyle != NULL && *opts->leafEdgeStyle)
gu_printf(out, err, "edge [style = %s];\n", opts->leafEdgeStyle);
gu_puts("\n", out, err);
GuSeq* alignment = NULL;
GuSeq* last_alignment = NULL;
for (size_t i = 0; i < n_concrs; i++) {
alignment = pgf_align_words(concrs[i], expr, err, tmp_pool);
gu_printf(out, err, " struct%d[label=\"", i);
size_t n_tokens = gu_seq_length(alignment);
for (size_t j = 0; j < n_tokens; j++) {
PgfAlignmentPhrase* phrase = gu_seq_get(alignment, PgfAlignmentPhrase*, j);
if (j > 0)
gu_puts(" | ", out, err);
gu_printf(out, err, "<n%d> %s", j, phrase->phrase);
}
gu_puts("\"] ;\n", out, err);
if (last_alignment != NULL) {
size_t n_last_tokens = gu_seq_length(last_alignment);
for (size_t j = 0; j < n_tokens; j++) {
PgfAlignmentPhrase* phrase = gu_seq_get(alignment, PgfAlignmentPhrase*, j);
for (size_t k = 0; k < phrase->n_fids; k++) {
int fid = phrase->fids[k];
for (size_t l = 0; l < n_last_tokens; l++) {
PgfAlignmentPhrase* last_phrase = gu_seq_get(last_alignment, PgfAlignmentPhrase*, l);
for (size_t r = 0; r < last_phrase->n_fids; r++) {
int last_fid = last_phrase->fids[r];
if (fid == last_fid) {
gu_printf(out, err, "struct%d:n%d:e -> struct%d:n%d:w ;\n",i,j,i-1,l);
}
}
}
}
}
}
last_alignment = alignment;
}
gu_puts("}", out, err);
gu_pool_free(tmp_pool);
}

View File

@@ -1,28 +0,0 @@
#ifndef PGF_GRAPHVIZ_H_
#define PGF_GRAPHVIZ_H_
typedef struct {
int noLeaves;
int noFun;
int noCat;
int noDep;
GuString nodeFont;
GuString leafFont;
GuString nodeColor;
GuString leafColor;
GuString nodeEdgeStyle;
GuString leafEdgeStyle;
} PgfGraphvizOptions;
extern PgfGraphvizOptions pgf_default_graphviz_options[1];
PGF_API_DECL void
pgf_graphviz_abstract_tree(PgfPGF* pgf, PgfExpr expr, PgfGraphvizOptions* opts, GuOut* out, GuExn* err);
PGF_API_DECL void
pgf_graphviz_parse_tree(PgfConcr* concr, PgfExpr expr, PgfGraphvizOptions* opts, GuOut* out, GuExn* err);
PGF_API_DECL void
pgf_graphviz_word_alignment(PgfConcr** concrs, size_t n_concrs, PgfExpr expr, PgfGraphvizOptions* opts, GuOut* out, GuExn* err);
#endif

View File

@@ -1,11 +0,0 @@
#include "data.h"
#include "reasoner.h"
#include "hopu.h"
PGF_INTERNAL void
pgf_pattern_unify(PgfReasoner* rs, PgfClosure* c1, PgfClosure* c2)
{
c1 = rs->eval_gates->enter(rs, c1);
c2 = rs->eval_gates->enter(rs, c2);
}

View File

@@ -1,8 +0,0 @@
#ifndef HOPU_H
#define HOPU_H
PGF_INTERNAL_DECL void
pgf_pattern_unify(PgfReasoner* rs, PgfClosure* c1, PgfClosure* c2);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,62 +0,0 @@
/******************************** -*- C -*- ****************************
*
* lightning main include file
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_h
#define __lightning_h
#ifdef __cplusplus
extern "C" {
#endif
#include "lightning/asm-common.h"
#ifndef LIGHTNING_DEBUG
#include "lightning/asm.h"
#endif
#include "lightning/core.h"
#include "lightning/core-common.h"
#include "lightning/funcs.h"
#include "lightning/funcs-common.h"
#include "lightning/fp.h"
#include "lightning/fp-common.h"
#ifndef JIT_R0
#error GNU lightning does not support the current target
#endif
#ifdef __cplusplus
}
#endif
#endif /* __lightning_h */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,193 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Run-time assembler for the arm
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2011 Free Software Foundation
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* Authors:
* Paulo Cesar Pereira de Andrade
***********************************************************************/
#ifndef __lightning_funcs_h
#define __lightning_funcs_h
#if defined(__linux__)
# include <stdio.h>
# include <string.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#if defined(ios_HOST_OS) || defined (darwin_HOST_OS)
extern void sys_icache_invalidate(void *start, size_t len);
static void
jit_flush_code(void *start, void *end)
{
mprotect(start, (char *)end - (char *)start,
PROT_READ | PROT_WRITE | PROT_EXEC);
sys_icache_invalidate(start, (char *)end-(char *)start);
}
#else
extern void __clear_cache(void*, void*);
static void
jit_flush_code(void *start, void *end)
{
mprotect(start, (char *)end - (char *)start,
PROT_READ | PROT_WRITE | PROT_EXEC);
__clear_cache(start, end);
}
#endif
__attribute__((constructor)) static void
jit_get_cpu(void)
{
#if defined(__linux__)
FILE *fp;
char *ptr;
char buf[128];
static int initialized;
if (initialized)
return;
initialized = 1;
if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
return;
while (fgets(buf, sizeof(buf), fp)) {
if (strncmp(buf, "CPU architecture:", 17) == 0) {
jit_cpu.version = strtol(buf + 17, &ptr, 10);
while (*ptr) {
if (*ptr == 'T' || *ptr == 't') {
++ptr;
jit_cpu.thumb = 1;
}
else if (*ptr == 'E' || *ptr == 'e') {
jit_cpu.extend = 1;
++ptr;
}
else
++ptr;
}
}
else if (strncmp(buf, "Features\t:", 10) == 0) {
if ((ptr = strstr(buf + 10, "vfpv")))
jit_cpu.vfp = strtol(ptr + 4, NULL, 0);
if ((ptr = strstr(buf + 10, "neon")))
jit_cpu.neon = 1;
if ((ptr = strstr(buf + 10, "thumb")))
jit_cpu.thumb = 1;
}
}
fclose(fp);
#endif
#if defined(__ARM_PCS_VFP)
if (!jit_cpu.vfp)
jit_cpu.vfp = 3;
if (!jit_cpu.version)
jit_cpu.version = 7;
jit_cpu.abi = 1;
#endif
/* armv6t2 todo (software float and thumb2) */
if (!jit_cpu.vfp && jit_cpu.thumb)
jit_cpu.thumb = 0;
}
extern int __aeabi_idivmod(int, int);
extern unsigned __aeabi_uidivmod(unsigned, unsigned);
#pragma push_macro("_jit")
#ifdef _jit
#undef _jit
#endif
#define _jit (*jit)
static void
arm_divmod(jit_state* jit, int div, int sign,
jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
{
int d;
int l;
void *p;
l = 0xf;
if ((int)r0 < 4)
/* bogus extra push to align at 8 bytes */
l = (l & ~(1 << r0)) | 0x10;
#ifdef USE_THUMB_CODE
T1_PUSH(l);
#else
_PUSH(l);
#endif
if (r1 == _R1 && r2 == _R0) {
jit_movr_i(JIT_FTMP, _R0);
jit_movr_i(_R0, _R1);
jit_movr_i(_R1, JIT_FTMP);
} else if (r2 == _R0) {
jit_movr_i(_R1, r2);
jit_movr_i(_R0, r1);
} else {
jit_movr_i(_R0, r1);
jit_movr_i(_R1, r2);
}
p = (sign) ? (void*) __aeabi_idivmod : (void*) __aeabi_uidivmod;
if (!jit_exchange_p()) {
#ifdef USE_THUMB_CODE
d = (((int)p - (int)_jit.x.pc) >> 1) - 2;
#else
d = (((int)p - (int)_jit.x.pc) >> 2) - 2;
#endif
if (_s24P(d)) {
#ifdef USE_THUMB_CODE
T2_BLI(encode_thumb_jump(d));
#else
_BLI(d & 0x00ffffff);
#endif
}
else
goto fallback;
} else {
fallback:
jit_movi_i(JIT_FTMP, (int)p);
#ifdef USE_THUMB_CODE
T1_BLX(JIT_FTMP);
#else
_BLX(JIT_FTMP);
#endif
}
if (div) {
jit_movr_i(r0, _R0);
} else {
jit_movr_i(r0, _R1);
}
#ifdef USE_THUMB_CODE
T1_POP(l);
#else
_POP(l);
#endif
}
#pragma pop_macro("_jit")
#endif /* __lightning_funcs_h */

View File

@@ -1,207 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Dynamic assembler support
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
***********************************************************************/
#ifndef __lightning_asm_common_h_
#define __lightning_asm_common_h_
#ifndef _ASM_SAFETY
#define JITFAIL(MSG) 0
#else
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || (defined __GNUC__ && (__GNUC__ == 3 ? __GNUC_MINOR__ >= 2 : __GNUC__ > 3))
#define JITFAIL(MSG) jit_fail(MSG, __FILE__, __LINE__, __func__)
#elif defined __GNUC__
#define JITFAIL(MSG) jit_fail(MSG, __FILE__, __LINE__, __FUNCTION__)
#else
#define JITFAIL(MSG) jit_fail(MSG, __FILE__, __LINE__, "(unknown)")
#endif
#endif
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || (defined __GNUC__ && (__GNUC__ == 3 ? __GNUC_MINOR__ >= 2 : __GNUC__ > 3))
#define JITSORRY(MSG) jit_fail("sorry, unimplemented: " MSG, __FILE__, __LINE__, __func__)
#elif defined __GNUC__
#define JITSORRY(MSG) jit_fail("sorry, unimplemented: " MSG, __FILE__, __LINE__, __FUNCTION__)
#else
#define JITSORRY(MSG) jit_fail("sorry, unimplemented: " MSG, __FILE__, __LINE__, "(unknown)")
#endif
#ifdef __GNUC__
#define JIT_UNUSED __attribute__((__unused__))
#else
#define JIT_UNUSED
#endif
/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
does not implement __extension__. But that compiler doesn't define
__GNUC_MINOR__. */
#ifdef __GNUC__
#if __GNUC__ < 2 || (defined(__NeXT__) && !__GNUC_MINOR__)
#define __extension__
#endif
#define _TEMPD(type, var)
#define _TEMP(type, var, val, body) __extension__ ({ \
register struct { type var } _jitl; _jitl.var = val; \
body; \
})
#else
/* Between loading a global and calling a subroutine, we choose the lesser
* evil. */
#define _TEMPD(type, var) static type var;
#define _TEMP(type, var, val, body) ((var = val), body)
#endif
typedef char _sc;
typedef unsigned char _uc;
typedef unsigned short _us;
typedef unsigned int _ui;
typedef long _sl;
typedef unsigned long _ul;
#define _jit_UC(X) ((_uc )(X))
#define _jit_US(X) ((_us )(X))
#define _jit_UI(X) ((_ui )(X))
#define _jit_SI(X) ((int )(X))
#define _jit_SL(X) ((_sl )(X))
#define _jit_UL(X) ((_ul )(X))
# define _PUC(X) ((_uc *)(X))
# define _PUS(X) ((_us *)(X))
# define _PUI(X) ((_ui *)(X))
# define _PSI(X) ((int *)(X))
# define _PSL(X) ((_sl *)(X))
# define _PUL(X) ((_ul *)(X))
#define _jit_B(B) _jit_UL(((*_jit.x.uc_pc++)= _jit_UC((B)& 0xff)))
#define _jit_W(W) _jit_UL(((*_jit.x.us_pc++)= _jit_US((W)&0xffff)))
#define _jit_I(I) _jit_UL(((*_jit.x.ui_pc++)= _jit_UI((I) )))
#define _jit_L(L) _jit_UL(((*_jit.x.ul_pc++)= _jit_UL((L) )))
#define _jit_I_noinc(I) _jit_UL(((*_jit.x.ui_pc)= _jit_UI((I) )))
#define _MASK(N) ((unsigned long)((1L<<(N)))-1L)
#define _siP(N,I) (!((((unsigned long)(I))^(((unsigned long)(I))<<1))&~_MASK(N)))
#define _uiP(N,I) (!(((unsigned long)(I))&~_MASK(N)))
#define _suiP(N,I) (_siP(N,I) | _uiP(N,I))
#ifndef _ASM_SAFETY
#define _ck_s(W,I) (_jit_UL(I) & _MASK(W))
#define _ck_u(W,I) (_jit_UL(I) & _MASK(W))
#define _ck_su(W,I) (_jit_UL(I) & _MASK(W))
#define _ck_d(W,I) (_jit_UL(I) & _MASK(W))
#else
#define _ck_s(W,I) (_siP(W,I) ? (_jit_UL(I) & _MASK(W)) : JITFAIL( "signed integer `"#I"' too large for "#W"-bit field"))
#define _ck_u(W,I) (_uiP(W,I) ? (_jit_UL(I) & _MASK(W)) : JITFAIL("unsigned integer `"#I"' too large for "#W"-bit field"))
#define _ck_su(W,I) (_suiP(W,I) ? (_jit_UL(I) & _MASK(W)) : JITFAIL( "integer `"#I"' too large for "#W"-bit field"))
#define _ck_d(W,I) (_siP(W,I) ? (_jit_UL(I) & _MASK(W)) : JITFAIL( "displacement `"#I"' too large for "#W"-bit field"))
#endif
#define _s0P(I) ((I)==0)
#define _s8P(I) _siP(8,I)
#define _s16P(I) _siP(16,I)
#define _s20P(I) _siP(20,I)
#define _s24P(I) _siP(24,I)
#define _s32P(I) _siP(32,I)
#define _u8P(I) _uiP(8,I)
#define _u16P(I) _uiP(16,I)
#define _u32P(I) _uiP(32,I)
#define _su8(I) _ck_su(8,I)
#define _su16(I) _ck_su(16,I)
#define _s1(I) _ck_s( 1,I)
#define _s2(I) _ck_s( 2,I)
#define _s3(I) _ck_s( 3,I)
#define _s4(I) _ck_s( 4,I)
#define _s5(I) _ck_s( 5,I)
#define _s6(I) _ck_s( 6,I)
#define _s7(I) _ck_s( 7,I)
#define _s8(I) _ck_s( 8,I)
#define _s9(I) _ck_s( 9,I)
#define _s10(I) _ck_s(10,I)
#define _s11(I) _ck_s(11,I)
#define _s12(I) _ck_s(12,I)
#define _s13(I) _ck_s(13,I)
#define _s14(I) _ck_s(14,I)
#define _s15(I) _ck_s(15,I)
#define _s16(I) _ck_s(16,I)
#define _s17(I) _ck_s(17,I)
#define _s18(I) _ck_s(18,I)
#define _s19(I) _ck_s(19,I)
#define _s20(I) _ck_s(20,I)
#define _s21(I) _ck_s(21,I)
#define _s22(I) _ck_s(22,I)
#define _s23(I) _ck_s(23,I)
#define _s24(I) _ck_s(24,I)
#define _s25(I) _ck_s(25,I)
#define _s26(I) _ck_s(26,I)
#define _s27(I) _ck_s(27,I)
#define _s28(I) _ck_s(28,I)
#define _s29(I) _ck_s(29,I)
#define _s30(I) _ck_s(30,I)
#define _s31(I) _ck_s(31,I)
#define _u1(I) _ck_u( 1,I)
#define _u2(I) _ck_u( 2,I)
#define _u3(I) _ck_u( 3,I)
#define _u4(I) _ck_u( 4,I)
#define _u5(I) _ck_u( 5,I)
#define _u6(I) _ck_u( 6,I)
#define _u7(I) _ck_u( 7,I)
#define _u8(I) _ck_u( 8,I)
#define _u9(I) _ck_u( 9,I)
#define _u10(I) _ck_u(10,I)
#define _u11(I) _ck_u(11,I)
#define _u12(I) _ck_u(12,I)
#define _u13(I) _ck_u(13,I)
#define _u14(I) _ck_u(14,I)
#define _u15(I) _ck_u(15,I)
#define _u16(I) _ck_u(16,I)
#define _u17(I) _ck_u(17,I)
#define _u18(I) _ck_u(18,I)
#define _u19(I) _ck_u(19,I)
#define _u20(I) _ck_u(20,I)
#define _u21(I) _ck_u(21,I)
#define _u22(I) _ck_u(22,I)
#define _u23(I) _ck_u(23,I)
#define _u24(I) _ck_u(24,I)
#define _u25(I) _ck_u(25,I)
#define _u26(I) _ck_u(26,I)
#define _u27(I) _ck_u(27,I)
#define _u28(I) _ck_u(28,I)
#define _u29(I) _ck_u(29,I)
#define _u30(I) _ck_u(30,I)
#define _u31(I) _ck_u(31,I)
#endif /* __lightning_asm_common_h */

View File

@@ -1,638 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer support
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_core_common_h_
#define __lightning_core_common_h_
typedef struct {
union {
jit_insn *pc;
_uc *uc_pc;
_us *us_pc;
_ui *ui_pc;
_ul *ul_pc;
} x;
struct jit_fp *fp;
struct jit_local_state jitl;
} jit_state;
#define JIT_NOREG (-1)
#define JIT_R0 JIT_R(0)
#define JIT_R1 JIT_R(1)
#define JIT_R2 JIT_R(2)
#define JIT_V0 JIT_V(0)
#define JIT_V1 JIT_V(1)
#define JIT_V2 JIT_V(2)
#define JIT_FPR0 JIT_FPR(0)
#define JIT_FPR1 JIT_FPR(1)
#define JIT_FPR2 JIT_FPR(2)
#define JIT_FPR3 JIT_FPR(3)
#define JIT_FPR4 JIT_FPR(4)
#define JIT_FPR5 JIT_FPR(5)
#define _jitl _jit.jitl
#define jit_get_ip() (*(jit_code *) &_jit.x.pc)
#define jit_set_ip(ptr) (_jit.x.pc = (ptr), jit_get_ip ())
#define jit_get_label() (_jit.x.pc)
#define jit_forward() (_jit.x.pc)
#define jit_field(struc, f) ( ((long) (&((struc *) 8)->f) ) - 8)
#define jit_ptr_field(struc_p, f) ( ((long) (&((struc_p) 8)->f) ) - 8)
/* realignment via N-byte no-ops */
#ifndef jit_align
#define jit_align(n)
#endif
/* jit_code: union of many possible function pointer types. Returned
* by jit_get_ip().
*/
typedef union jit_code {
char *ptr;
void (*vptr)(void);
char (*cptr)(void);
unsigned char (*ucptr)(void);
short (*sptr)(void);
unsigned short (*usptr)(void);
int (*iptr)(void);
unsigned int (*uiptr)(void);
long (*lptr)(void);
unsigned long (*ulptr)(void);
void * (*pptr)(void);
float (*fptr)(void);
double (*dptr)(void);
} jit_code;
#ifndef jit_fill_delay_after
#define jit_fill_delay_after(branch) (branch)
#endif
#define jit_delay(insn, branch) ((insn), jit_fill_delay_after(branch))
/* ALU synonyms */
#define jit_addi_ui(d, rs, is) jit_addi_i((d), (rs), (is))
#define jit_addr_ui(d, s1, s2) jit_addr_i((d), (s1), (s2))
#define jit_addci_ui(d, rs, is) jit_addci_i((d), (rs), (is))
#define jit_addcr_ui(d, s1, s2) jit_addcr_i((d), (s1), (s2))
#define jit_addxi_ui(d, rs, is) jit_addxi_i((d), (rs), (is))
#define jit_addxr_ui(d, s1, s2) jit_addxr_i((d), (s1), (s2))
#define jit_andi_ui(d, rs, is) jit_andi_i((d), (rs), (is))
#define jit_andr_ui(d, s1, s2) jit_andr_i((d), (s1), (s2))
#define jit_lshi_ui(d, rs, is) jit_lshi_i((d), (rs), (is))
#define jit_lshr_ui(d, s1, s2) jit_lshr_i((d), (s1), (s2))
#define jit_movi_ui(d, rs) jit_movi_i((d), (rs))
#define jit_movr_ui(d, rs) jit_movr_i((d), (rs))
#define jit_ori_ui(d, rs, is) jit_ori_i((d), (rs), (is))
#define jit_orr_ui(d, s1, s2) jit_orr_i((d), (s1), (s2))
#define jit_rsbi_ui(d, rs, is) jit_rsbi_i((d), (rs), (is))
#define jit_rsbr_ui(d, s1, s2) jit_rsbr_i((d), (s1), (s2))
#define jit_subi_ui(d, rs, is) jit_subi_i((d), (rs), (is))
#define jit_subr_ui(d, s1, s2) jit_subr_i((d), (s1), (s2))
#define jit_subci_ui(d, rs, is) jit_subci_i((d), (rs), (is))
#define jit_subcr_ui(d, s1, s2) jit_subcr_i((d), (s1), (s2))
#define jit_subxi_ui(d, rs, is) jit_subxi_i((d), (rs), (is))
#define jit_subxr_ui(d, s1, s2) jit_subxr_i((d), (s1), (s2))
#define jit_xori_ui(d, rs, is) jit_xori_i((d), (rs), (is))
#define jit_xorr_ui(d, s1, s2) jit_xorr_i((d), (s1), (s2))
#define jit_addi_ul(d, rs, is) jit_addi_l((d), (rs), (is))
#define jit_addr_ul(d, s1, s2) jit_addr_l((d), (s1), (s2))
#define jit_addci_ul(d, rs, is) jit_addci_l((d), (rs), (is))
#define jit_addcr_ul(d, s1, s2) jit_addcr_l((d), (s1), (s2))
#define jit_addxi_ul(d, rs, is) jit_addxi_l((d), (rs), (is))
#define jit_addxr_ul(d, s1, s2) jit_addxr_l((d), (s1), (s2))
#define jit_andi_ul(d, rs, is) jit_andi_l((d), (rs), (is))
#define jit_andr_ul(d, s1, s2) jit_andr_l((d), (s1), (s2))
#define jit_lshi_ul(d, rs, is) jit_lshi_l((d), (rs), (is))
#define jit_lshr_ul(d, s1, s2) jit_lshr_l((d), (s1), (s2))
#define jit_movi_ul(d, rs) jit_movi_l((d), (rs))
#define jit_movr_ul(d, rs) jit_movr_l((d), (rs))
#define jit_ori_ul(d, rs, is) jit_ori_l((d), (rs), (is))
#define jit_orr_ul(d, s1, s2) jit_orr_l((d), (s1), (s2))
#define jit_rsbi_ul(d, rs, is) jit_rsbi_l((d), (rs), (is))
#define jit_rsbr_ul(d, s1, s2) jit_rsbr_l((d), (s1), (s2))
#define jit_subi_ul(d, rs, is) jit_subi_l((d), (rs), (is))
#define jit_subr_ul(d, s1, s2) jit_subr_l((d), (s1), (s2))
#define jit_subci_ul(d, rs, is) jit_subci_l((d), (rs), (is))
#define jit_subcr_ul(d, s1, s2) jit_subcr_l((d), (s1), (s2))
#define jit_subxi_ui(d, rs, is) jit_subxi_i((d), (rs), (is))
#define jit_subxi_ul(d, rs, is) jit_subxi_l((d), (rs), (is))
#define jit_subxr_ui(d, s1, s2) jit_subxr_i((d), (s1), (s2))
#define jit_subxr_ul(d, s1, s2) jit_subxr_i((d), (s1), (s2))
#define jit_xori_ul(d, rs, is) jit_xori_l((d), (rs), (is))
#define jit_xorr_ul(d, s1, s2) jit_xorr_l((d), (s1), (s2))
#define jit_addr_p(d, s1, s2) jit_addr_ul((d), (s1), (s2))
#define jit_addi_p(d, rs, is) (jit_addi_ul((d), (rs), (long) (is)), _jit.x.pc)
#define jit_movr_p(d, rs) jit_movr_ul((d), (rs))
#define jit_subr_p(d, s1, s2) jit_subr_ul((d), (s1), (s2))
#define jit_subi_p(d, rs, is) jit_subi_ul((d), (rs), (long) (is))
#define jit_rsbi_p(d, rs, is) jit_rsbi_ul((d), (rs), (long) (is))
#ifndef jit_movi_p
#define jit_movi_p(d, is) (jit_movi_ul((d), (long) (is)), _jit.x.pc)
#endif
#define jit_patch(pv) jit_patch_at ((pv), (_jit.x.pc))
#ifndef jit_addci_i
#define jit_addci_i(d, rs, is) jit_addi_i((d), (rs), (is))
#define jit_addcr_i(d, s1, s2) jit_addr_i((d), (s1), (s2))
#define jit_addci_l(d, rs, is) jit_addi_l((d), (rs), (is))
#define jit_addcr_l(d, s1, s2) jit_addr_l((d), (s1), (s2))
#endif
#ifndef jit_subcr_i
#define jit_subcr_i(d, s1, s2) jit_subr_i((d), (s1), (s2))
#endif
/* NEG is not mandatory -- pick an appropriate implementation */
#ifndef jit_negr_i
# ifdef JIT_RZERO
# define jit_negr_i(d, rs) jit_subr_i((d), JIT_RZERO, (rs))
# define jit_negr_l(d, rs) jit_subr_l((d), JIT_RZERO, (rs))
# else /* !JIT_RZERO */
# ifndef jit_rsbi_i
# define jit_negr_i(d, rs) (jit_xori_i((d), (rs), -1), jit_addi_l((d), (d), 1))
# define jit_negr_l(d, rs) (jit_xori_l((d), (rs), -1), jit_addi_l((d), (d), 1))
# else /* jit_rsbi_i */
# define jit_negr_i(d, rs) jit_rsbi_i((d), (rs), 0)
# define jit_negr_l(d, rs) jit_rsbi_l((d), (rs), 0)
# endif /* jit_rsbi_i */
# endif /* !JIT_RZERO */
#endif /* !jit_negr_i */
/* RSB is not mandatory */
#ifndef jit_rsbi_i
# define jit_rsbi_i(d, rs, is) (jit_subi_i((d), (rs), (is)), jit_negr_i((d), (d)))
# ifndef jit_rsbi_l
# define jit_rsbi_l(d, rs, is) (jit_subi_l((d), (rs), (is)), jit_negr_l((d), (d)))
# endif
#endif
/* Common 'shortcut' implementations */
#ifndef jit_subi_i
#define jit_subi_i(d, rs, is) jit_addi_i((d), (rs), -(is))
#endif
#define jit_subi_l(d, rs, is) jit_addi_l((d), (rs), -(is))
#ifndef jit_subci_i
#define jit_subci_i(d, rs, is) jit_addci_i((d), (rs), -(is))
#endif
#define jit_subci_l(d, rs, is) jit_addci_l((d), (rs), -(is))
#define jit_rsbr_f(d, s1, s2) jit_subr_f((d), (s2), (s1))
#define jit_rsbr_d(d, s1, s2) jit_subr_d((d), (s2), (s1))
#ifndef jit_rsbr_i
#define jit_rsbr_i(d, s1, s2) jit_subr_i((d), (s2), (s1))
#endif
#define jit_rsbr_l(d, s1, s2) jit_subr_l((d), (s2), (s1))
#define jit_rsbr_p(d, s1, s2) jit_subr_p((d), (s2), (s1))
/* Unary */
#define jit_notr_c(d, rs) jit_xori_c((d), (rs), 255)
#define jit_notr_uc(d, rs) jit_xori_c((d), (rs), 255)
#define jit_notr_s(d, rs) jit_xori_s((d), (rs), 65535)
#define jit_notr_us(d, rs) jit_xori_s((d), (rs), 65535)
#ifndef jit_notr_i
#define jit_notr_i(d, rs) jit_xori_i((d), (rs), ~0)
#endif
#define jit_notr_ui(d, rs) jit_xori_i((d), (rs), ~0)
#define jit_notr_l(d, rs) jit_xori_l((d), (rs), ~0L)
#define jit_notr_ul(d, rs) jit_xori_l((d), (rs), ~0L)
#ifndef jit_extr_c_ui
#define jit_extr_c_ui(d, rs) jit_andi_ui((d), (rs), 0xFF)
#endif
#ifndef jit_extr_s_ui
#define jit_extr_s_ui(d, rs) jit_andi_ui((d), (rs), 0xFFFF)
#endif
#ifndef jit_extr_c_i
#define jit_extr_c_i(d, rs) (jit_lshi_i((d), (rs), 24), jit_rshi_i((d), (d), 24))
#endif
#ifndef jit_extr_s_i
#define jit_extr_s_i(d, rs) (jit_lshi_i((d), (rs), 16), jit_rshi_i((d), (d), 16))
#endif
#ifdef jit_addi_l /* sizeof(long) != sizeof(int) */
#ifndef jit_extr_c_l
#define jit_extr_c_l(d, rs) (jit_lshi_l((d), (rs), 56), jit_rshi_l((d), (d), 56))
#endif
#ifndef jit_extr_s_l
#define jit_extr_s_l(d, rs) (jit_lshi_l((d), (rs), 48), jit_rshi_l((d), (d), 48))
#endif
#ifndef jit_extr_i_l
#define jit_extr_i_l(d, rs) (jit_lshi_l((d), (rs), 32), jit_rshi_l((d), (d), 32))
#endif
#ifndef jit_extr_c_ul
#define jit_extr_c_ul(d, rs) jit_andi_l((d), (rs), 0xFF)
#endif
#ifndef jit_extr_s_ul
#define jit_extr_s_ul(d, rs) jit_andi_l((d), (rs), 0xFFFF)
#endif
#ifndef jit_extr_i_ul
#define jit_extr_i_ul(d, rs) jit_andi_l((d), (rs), 0xFFFFFFFFUL)
#endif
#endif
#define jit_extr_c_s(d, rs) jit_extr_c_i((d), (rs))
#define jit_extr_c_us(d, rs) jit_extr_c_ui((d), (rs))
#define jit_extr_uc_s(d, rs) jit_extr_uc_i((d), (rs))
#define jit_extr_uc_us(d, rs) jit_extr_uc_ui((d), (rs))
#define jit_extr_uc_i(d, rs) jit_extr_c_ui((d), (rs))
#define jit_extr_uc_ui(d, rs) jit_extr_c_ui((d), (rs))
#define jit_extr_us_i(d, rs) jit_extr_s_ui((d), (rs))
#define jit_extr_us_ui(d, rs) jit_extr_s_ui((d), (rs))
#define jit_extr_uc_l(d, rs) jit_extr_c_ul((d), (rs))
#define jit_extr_uc_ul(d, rs) jit_extr_c_ul((d), (rs))
#define jit_extr_us_l(d, rs) jit_extr_s_ul((d), (rs))
#define jit_extr_us_ul(d, rs) jit_extr_s_ul((d), (rs))
#define jit_extr_ui_l(d, rs) jit_extr_i_ul((d), (rs))
#define jit_extr_ui_ul(d, rs) jit_extr_i_ul((d), (rs))
/* NTOH/HTON is not mandatory for big endian architectures */
#ifndef jit_ntoh_ui /* big endian */
#define jit_ntoh_ui(d, rs) ((d) == (rs) ? (void)0 : jit_movr_i((d), (rs)))
#define jit_ntoh_us(d, rs) ((d) == (rs) ? (void)0 : jit_movr_i((d), (rs)))
#endif /* big endian */
/* hton is a synonym for ntoh */
#define jit_hton_ui(d, rs) jit_ntoh_ui((d), (rs))
#define jit_hton_us(d, rs) jit_ntoh_us((d), (rs))
/* Stack synonyms */
#define jit_pushr_ui(rs) jit_pushr_i(rs)
#define jit_popr_ui(rs) jit_popr_i(rs)
#define jit_pushr_ul(rs) jit_pushr_l(rs)
#define jit_popr_ul(rs) jit_popr_l(rs)
#define jit_pushr_p(rs) jit_pushr_ul(rs)
#define jit_popr_p(rs) jit_popr_ul(rs)
#define jit_prepare(nint) jit_prepare_i((nint))
#define jit_pusharg_c(rs) jit_pusharg_i(rs)
#define jit_pusharg_s(rs) jit_pusharg_i(rs)
#define jit_pusharg_uc(rs) jit_pusharg_i(rs)
#define jit_pusharg_us(rs) jit_pusharg_i(rs)
#define jit_pusharg_ui(rs) jit_pusharg_i(rs)
#define jit_pusharg_ul(rs) jit_pusharg_l(rs)
#define jit_pusharg_p(rs) jit_pusharg_ul(rs)
/* Memory synonyms */
#ifdef JIT_RZERO
#ifndef jit_ldi_c
#define jit_ldi_c(rd, is) jit_ldxi_c((rd), JIT_RZERO, (is))
#define jit_sti_c(id, rs) jit_stxi_c((id), JIT_RZERO, (rs))
#define jit_ldi_s(rd, is) jit_ldxi_s((rd), JIT_RZERO, (is))
#define jit_sti_s(id, rs) jit_stxi_s((id), JIT_RZERO, (rs))
#define jit_ldi_i(rd, is) jit_ldxi_i((rd), JIT_RZERO, (is))
#define jit_sti_i(id, rs) jit_stxi_i((id), JIT_RZERO, (rs))
#define jit_ldi_l(rd, is) jit_ldxi_l((rd), JIT_RZERO, (is))
#define jit_sti_l(id, rs) jit_stxi_l((id), JIT_RZERO, (rs))
#define jit_ldi_uc(rd, is) jit_ldxi_uc((rd), JIT_RZERO, (is))
#define jit_ldi_us(rd, is) jit_ldxi_us((rd), JIT_RZERO, (is))
#define jit_ldi_ui(rd, is) jit_ldxi_ui((rd), JIT_RZERO, (is))
#define jit_ldi_ul(rd, is) jit_ldxi_ul((rd), JIT_RZERO, (is))
#endif
#ifndef jit_ldr_c
#define jit_ldr_c(rd, rs) jit_ldxr_c((rd), JIT_RZERO, (rs))
#define jit_str_c(rd, rs) jit_stxr_c(JIT_RZERO, (rd), (rs))
#define jit_ldr_s(rd, rs) jit_ldxr_s((rd), JIT_RZERO, (rs))
#define jit_str_s(rd, rs) jit_stxr_s(JIT_RZERO, (rd), (rs))
#define jit_ldr_i(rd, rs) jit_ldxr_i((rd), JIT_RZERO, (rs))
#define jit_str_i(rd, rs) jit_stxr_i(JIT_RZERO, (rd), (rs))
#define jit_ldr_l(rd, rs) jit_ldxr_l((rd), JIT_RZERO, (rs))
#define jit_str_l(rd, rs) jit_stxr_l(JIT_RZERO, (rd), (rs))
#define jit_ldr_uc(rd, rs) jit_ldxr_uc((rd), JIT_RZERO, (rs))
#define jit_ldr_us(rd, rs) jit_ldxr_us((rd), JIT_RZERO, (rs))
#define jit_ldr_ui(rd, rs) jit_ldxr_ui((rd), JIT_RZERO, (rs))
#define jit_ldr_ul(rd, rs) jit_ldxr_ul((rd), JIT_RZERO, (rs))
#endif
#endif
#define jit_str_uc(rd, rs) jit_str_c((rd), (rs))
#define jit_sti_uc(id, rs) jit_sti_c((id), (rs))
#define jit_stxr_uc(d1, d2, rs) jit_stxr_c((d1), (d2), (rs))
#define jit_stxi_uc(id, rd, is) jit_stxi_c((id), (rd), (is))
#define jit_str_us(rd, rs) jit_str_s((rd), (rs))
#define jit_sti_us(id, rs) jit_sti_s((id), (rs))
#define jit_stxr_us(d1, d2, rs) jit_stxr_s((d1), (d2), (rs))
#define jit_stxi_us(id, rd, is) jit_stxi_s((id), (rd), (is))
#define jit_str_ui(rd, rs) jit_str_i((rd), (rs))
#define jit_sti_ui(id, rs) jit_sti_i((id), (rs))
#define jit_stxr_ui(d1, d2, rs) jit_stxr_i((d1), (d2), (rs))
#define jit_stxi_ui(id, rd, is) jit_stxi_i((id), (rd), (is))
#define jit_str_ul(rd, rs) jit_str_l((rd), (rs))
#define jit_sti_ul(id, rs) jit_sti_l((id), (rs))
#define jit_stxr_ul(d1, d2, rs) jit_stxr_l((d1), (d2), (rs))
#define jit_stxi_ul(id, rd, is) jit_stxi_l((id), (rd), (is))
#define jit_str_p(rd, rs) jit_str_l((rd), (rs))
#define jit_sti_p(id, rs) jit_sti_l((id), (rs))
#define jit_stxr_p(d1, d2, rs) jit_stxr_l((d1), (d2), (rs))
#define jit_stxi_p(id, rd, is) jit_stxi_l((id), (rd), (is))
#define jit_ldr_p(rd, rs) jit_ldr_l((rd), (rs))
#define jit_ldi_p(rd, is) jit_ldi_l((rd), (is))
#define jit_ldxr_p(rd, s1, s2) jit_ldxr_l((rd), (s1), (s2))
#define jit_ldxi_p(rd, rs, is) jit_ldxi_l((rd), (rs), (is))
/* Boolean & branch synonyms */
#define jit_eqr_ui(d, s1, s2) jit_eqr_i((d), (s1), (s2))
#define jit_eqi_ui(d, rs, is) jit_eqi_i((d), (rs), (is))
#define jit_ner_ui(d, s1, s2) jit_ner_i((d), (s1), (s2))
#define jit_nei_ui(d, rs, is) jit_nei_i((d), (rs), (is))
#define jit_eqr_ul(d, s1, s2) jit_eqr_l((d), (s1), (s2))
#define jit_eqi_ul(d, rs, is) jit_eqi_l((d), (rs), (is))
#define jit_ner_ul(d, s1, s2) jit_ner_l((d), (s1), (s2))
#define jit_nei_ul(d, rs, is) jit_nei_l((d), (rs), (is))
#define jit_beqr_ui(label, s1, s2) jit_beqr_i((label), (s1), (s2))
#define jit_beqi_ui(label, rs, is) jit_beqi_i((label), (rs), (is))
#define jit_bner_ui(label, s1, s2) jit_bner_i((label), (s1), (s2))
#define jit_bnei_ui(label, rs, is) jit_bnei_i((label), (rs), (is))
#define jit_bmcr_ui(label, s1, s2) jit_bmcr_i((label), (s1), (s2))
#define jit_bmci_ui(label, rs, is) jit_bmci_i((label), (rs), (is))
#define jit_bmsr_ui(label, s1, s2) jit_bmsr_i((label), (s1), (s2))
#define jit_bmsi_ui(label, rs, is) jit_bmsi_i((label), (rs), (is))
#define jit_beqr_ul(label, s1, s2) jit_beqr_l((label), (s1), (s2))
#define jit_beqi_ul(label, rs, is) jit_beqi_l((label), (rs), (is))
#define jit_bner_ul(label, s1, s2) jit_bner_l((label), (s1), (s2))
#define jit_bnei_ul(label, rs, is) jit_bnei_l((label), (rs), (is))
#define jit_bmcr_ul(label, s1, s2) jit_bmcr_l((label), (s1), (s2))
#define jit_bmci_ul(label, rs, is) jit_bmci_l((label), (rs), (is))
#define jit_bmsr_ul(label, s1, s2) jit_bmsr_l((label), (s1), (s2))
#define jit_bmsi_ul(label, rs, is) jit_bmsi_l((label), (rs), (is))
#define jit_ltr_p(d, s1, s2) jit_ltr_ul((d), (s1), (s2))
#define jit_lti_p(d, rs, is) jit_lti_ul((d), (rs), (is))
#define jit_ler_p(d, s1, s2) jit_ler_ul((d), (s1), (s2))
#define jit_lei_p(d, rs, is) jit_lei_ul((d), (rs), (is))
#define jit_gtr_p(d, s1, s2) jit_gtr_ul((d), (s1), (s2))
#define jit_gti_p(d, rs, is) jit_gti_ul((d), (rs), (is))
#define jit_ger_p(d, s1, s2) jit_ger_ul((d), (s1), (s2))
#define jit_gei_p(d, rs, is) jit_gei_ul((d), (rs), (is))
#define jit_eqr_p(d, s1, s2) jit_eqr_ul((d), (s1), (s2))
#define jit_eqi_p(d, rs, is) jit_eqi_ul((d), (rs), (is))
#define jit_ner_p(d, s1, s2) jit_ner_ul((d), (s1), (s2))
#define jit_nei_p(d, rs, is) jit_nei_ul((d), (rs), (is))
#define jit_bltr_p(label, s1, s2) jit_bltr_ul((label), (s1), (s2))
#define jit_blti_p(label, rs, is) jit_blti_ul((label), (rs), (is))
#define jit_bler_p(label, s1, s2) jit_bler_ul((label), (s1), (s2))
#define jit_blei_p(label, rs, is) jit_blei_ul((label), (rs), (is))
#define jit_bgtr_p(label, s1, s2) jit_bgtr_ul((label), (s1), (s2))
#define jit_bgti_p(label, rs, is) jit_bgti_ul((label), (rs), (is))
#define jit_bger_p(label, s1, s2) jit_bger_ul((label), (s1), (s2))
#define jit_bgei_p(label, rs, is) jit_bgei_ul((label), (rs), (is))
#define jit_beqr_p(label, s1, s2) jit_beqr_ul((label), (s1), (s2))
#define jit_beqi_p(label, rs, is) jit_beqi_ul((label), (rs), (is))
#define jit_bner_p(label, s1, s2) jit_bner_ul((label), (s1), (s2))
#define jit_bnei_p(label, rs, is) jit_bnei_ul((label), (rs), _jit_UL(is))
#define jit_retval_ui(rd) jit_retval_i((rd))
#define jit_retval_uc(rd) jit_retval_i((rd))
#define jit_retval_us(rd) jit_retval_i((rd))
#define jit_retval_ul(rd) jit_retval_l((rd))
#define jit_retval_p(rd) jit_retval_ul((rd))
#define jit_retval_c(rd) jit_retval_i((rd))
#define jit_retval_s(rd) jit_retval_i((rd))
/* This was a bug, but we keep it. */
#define jit_retval(rd) jit_retval_i ((rd))
#ifndef jit_finish
#define jit_finish(sub) jit_calli(sub)
#endif
#ifndef jit_finishr
#define jit_finishr(reg) jit_callr(reg)
#endif
#ifndef jit_prolog
#define jit_prolog(numargs)
#endif
#ifndef jit_leaf
#define jit_leaf(numargs) jit_prolog(numargs)
#endif
#ifndef jit_getarg_c
#ifndef JIT_FP
#define jit_getarg_c(reg, ofs) jit_extr_c_i ((reg), (ofs))
#define jit_getarg_i(reg, ofs) jit_movr_i ((reg), (ofs))
#define jit_getarg_l(reg, ofs) jit_movr_l ((reg), (ofs))
#define jit_getarg_p(reg, ofs) jit_movr_p ((reg), (ofs))
#define jit_getarg_s(reg, ofs) jit_extr_s_i ((reg), (ofs))
#define jit_getarg_uc(reg, ofs) jit_extr_uc_ui((reg), (ofs))
#define jit_getarg_ui(reg, ofs) jit_movr_ui ((reg), (ofs))
#define jit_getarg_ul(reg, ofs) jit_extr_uc_ul((reg), (ofs))
#define jit_getarg_us(reg, ofs) jit_extr_us_ul((reg), (ofs))
#else
#define jit_getarg_c(reg, ofs) jit_ldxi_c((reg), JIT_FP, (ofs));
#define jit_getarg_uc(reg, ofs) jit_ldxi_uc((reg), JIT_FP, (ofs));
#define jit_getarg_s(reg, ofs) jit_ldxi_s((reg), JIT_FP, (ofs));
#define jit_getarg_us(reg, ofs) jit_ldxi_us((reg), JIT_FP, (ofs));
#define jit_getarg_i(reg, ofs) jit_ldxi_i((reg), JIT_FP, (ofs));
#define jit_getarg_ui(reg, ofs) jit_ldxi_ui((reg), JIT_FP, (ofs));
#define jit_getarg_l(reg, ofs) jit_ldxi_l((reg), JIT_FP, (ofs));
#define jit_getarg_ul(reg, ofs) jit_ldxi_ul((reg), JIT_FP, (ofs));
#define jit_getarg_p(reg, ofs) jit_ldxi_p((reg), JIT_FP, (ofs));
#endif
#endif
#ifndef jit_setarg_p
#ifdef JIT_FP
#define jit_setarg_p(reg, ofs) jit_stxi_p((ofs), JIT_FP, (reg));
#endif
#endif
/* Common definitions when sizeof(long) = sizeof(int) */
#ifndef jit_addi_l
#define JIT_LONG_IS_INT
/* ALU */
#define jit_addi_l(d, rs, is) jit_addi_i((d), (rs), (is))
#define jit_addr_l(d, s1, s2) jit_addr_i((d), (s1), (s2))
#define jit_addci_l(d, rs, is) jit_addci_i((d), (rs), (is))
#define jit_addcr_l(d, s1, s2) jit_addcr_i((d), (s1), (s2))
#define jit_addxi_l(d, rs, is) jit_addxi_i((d), (rs), (is))
#define jit_addxr_l(d, s1, s2) jit_addxr_i((d), (s1), (s2))
#define jit_andi_l(d, rs, is) jit_andi_i((d), (rs), (is))
#define jit_andr_l(d, s1, s2) jit_andr_i((d), (s1), (s2))
#define jit_divi_l(d, rs, is) jit_divi_i((d), (rs), (is))
#define jit_divr_l(d, s1, s2) jit_divr_i((d), (s1), (s2))
#define jit_hmuli_l(d, rs, is) jit_hmuli_i((d), (rs), (is))
#define jit_hmulr_l(d, s1, s2) jit_hmulr_i((d), (s1), (s2))
#define jit_lshi_l(d, rs, is) jit_lshi_i((d), (rs), (is))
#define jit_lshr_l(d, s1, s2) jit_lshr_i((d), (s1), (s2))
#define jit_modi_l(d, rs, is) jit_modi_i((d), (rs), (is))
#define jit_modr_l(d, s1, s2) jit_modr_i((d), (s1), (s2))
#define jit_muli_l(d, rs, is) jit_muli_i((d), (rs), (is))
#define jit_mulr_l(d, s1, s2) jit_mulr_i((d), (s1), (s2))
#define jit_ori_l(d, rs, is) jit_ori_i((d), (rs), (is))
#define jit_orr_l(d, s1, s2) jit_orr_i((d), (s1), (s2))
#define jit_rshi_l(d, rs, is) jit_rshi_i((d), (rs), (is))
#define jit_rshr_l(d, s1, s2) jit_rshr_i((d), (s1), (s2))
#define jit_subr_l(d, s1, s2) jit_subr_i((d), (s1), (s2))
#define jit_subcr_l(d, s1, s2) jit_subcr_i((d), (s1), (s2))
#define jit_subxi_l(d, rs, is) jit_subxi_i((d), (rs), (is))
#define jit_subxr_l(d, s1, s2) jit_subxr_i((d), (s1), (s2))
#define jit_xori_l(d, rs, is) jit_xori_i((d), (rs), (is))
#define jit_xorr_l(d, s1, s2) jit_xorr_i((d), (s1), (s2))
#ifndef jit_rsbi_l
#define jit_rsbi_l(d, rs, is) jit_rsbi_i((d), (rs), (is))
#endif
#define jit_divi_ul(d, rs, is) jit_divi_ui((d), (rs), (is))
#define jit_divr_ul(d, s1, s2) jit_divr_ui((d), (s1), (s2))
#define jit_hmuli_ul(d, rs, is) jit_hmuli_ui((d), (rs), (is))
#define jit_hmulr_ul(d, s1, s2) jit_hmulr_ui((d), (s1), (s2))
#define jit_modi_ul(d, rs, is) jit_modi_ui((d), (rs), (is))
#define jit_modr_ul(d, s1, s2) jit_modr_ui((d), (s1), (s2))
#define jit_muli_ul(d, rs, is) jit_muli_ui((d), (rs), (is))
#define jit_mulr_ul(d, s1, s2) jit_mulr_ui((d), (s1), (s2))
#define jit_rshi_ul(d, rs, is) jit_rshi_ui((d), (rs), (is))
#define jit_rshr_ul(d, s1, s2) jit_rshr_ui((d), (s1), (s2))
/* Sign/Zero extension */
#define jit_extr_c_l(d, rs) jit_extr_c_i(d, rs)
#define jit_extr_c_ul(d, rs) jit_extr_c_ui(d, rs)
#define jit_extr_s_l(d, rs) jit_extr_s_i(d, rs)
#define jit_extr_s_ul(d, rs) jit_extr_s_ui(d, rs)
#define jit_extr_i_l(d, rs) jit_movr_i(d, rs)
#define jit_extr_i_ul(d, rs) jit_movr_i(d, rs)
/* Unary */
#define jit_movi_l(d, rs) jit_movi_i((d), (rs))
#define jit_movr_l(d, rs) jit_movr_i((d), (rs))
/* Stack */
#define jit_pushr_l(rs) jit_pushr_i(rs)
#define jit_popr_l(rs) jit_popr_i(rs)
#define jit_pusharg_l(rs) jit_pusharg_i(rs)
/* Memory */
#ifndef JIT_RZERO
#define jit_ldr_l(d, rs) jit_ldr_i((d), (rs))
#define jit_ldi_l(d, is) jit_ldi_i((d), (is))
#define jit_str_l(d, rs) jit_str_i((d), (rs))
#define jit_sti_l(d, is) jit_sti_i((d), (is))
#define jit_ldr_ui(d, rs) jit_ldr_i((d), (rs))
#define jit_ldi_ui(d, is) jit_ldi_i((d), (is))
#define jit_ldr_ul(d, rs) jit_ldr_ui((d), (rs))
#define jit_ldi_ul(d, is) jit_ldi_ui((d), (is))
#endif
#define jit_ldxr_l(d, s1, s2) jit_ldxr_i((d), (s1), (s2))
#define jit_ldxi_l(d, rs, is) jit_ldxi_i((d), (rs), (is))
#define jit_stxr_l(d, s1, s2) jit_stxr_i((d), (s1), (s2))
#define jit_stxi_l(d, rs, is) jit_stxi_i((d), (rs), (is))
#define jit_ldxr_ui(d, s1, s2) jit_ldxr_i((d), (s1), (s2))
#define jit_ldxi_ui(d, rs, is) jit_ldxi_i((d), (rs), (is))
#define jit_ldxr_ul(d, s1, s2) jit_ldxr_ui((d), (s1), (s2))
#define jit_ldxi_ul(d, rs, is) jit_ldxi_ui((d), (rs), (is))
/* Boolean */
#define jit_ltr_l(d, s1, s2) jit_ltr_i((d), (s1), (s2))
#define jit_lti_l(d, rs, is) jit_lti_i((d), (rs), (is))
#define jit_ler_l(d, s1, s2) jit_ler_i((d), (s1), (s2))
#define jit_lei_l(d, rs, is) jit_lei_i((d), (rs), (is))
#define jit_gtr_l(d, s1, s2) jit_gtr_i((d), (s1), (s2))
#define jit_gti_l(d, rs, is) jit_gti_i((d), (rs), (is))
#define jit_ger_l(d, s1, s2) jit_ger_i((d), (s1), (s2))
#define jit_gei_l(d, rs, is) jit_gei_i((d), (rs), (is))
#define jit_eqr_l(d, s1, s2) jit_eqr_i((d), (s1), (s2))
#define jit_eqi_l(d, rs, is) jit_eqi_i((d), (rs), (is))
#define jit_ner_l(d, s1, s2) jit_ner_i((d), (s1), (s2))
#define jit_nei_l(d, rs, is) jit_nei_i((d), (rs), (is))
#define jit_ltr_ul(d, s1, s2) jit_ltr_ui((d), (s1), (s2))
#define jit_lti_ul(d, rs, is) jit_lti_ui((d), (rs), (is))
#define jit_ler_ul(d, s1, s2) jit_ler_ui((d), (s1), (s2))
#define jit_lei_ul(d, rs, is) jit_lei_ui((d), (rs), (is))
#define jit_gtr_ul(d, s1, s2) jit_gtr_ui((d), (s1), (s2))
#define jit_gti_ul(d, rs, is) jit_gti_ui((d), (rs), (is))
#define jit_ger_ul(d, s1, s2) jit_ger_ui((d), (s1), (s2))
#define jit_gei_ul(d, rs, is) jit_gei_ui((d), (rs), (is))
/* Branches */
#define jit_bltr_l(label, s1, s2) jit_bltr_i((label), (s1), (s2))
#define jit_blti_l(label, rs, is) jit_blti_i((label), (rs), (is))
#define jit_bler_l(label, s1, s2) jit_bler_i((label), (s1), (s2))
#define jit_blei_l(label, rs, is) jit_blei_i((label), (rs), (is))
#define jit_bgtr_l(label, s1, s2) jit_bgtr_i((label), (s1), (s2))
#define jit_bgti_l(label, rs, is) jit_bgti_i((label), (rs), (is))
#define jit_bger_l(label, s1, s2) jit_bger_i((label), (s1), (s2))
#define jit_bgei_l(label, rs, is) jit_bgei_i((label), (rs), (is))
#define jit_beqr_l(label, s1, s2) jit_beqr_i((label), (s1), (s2))
#define jit_beqi_l(label, rs, is) jit_beqi_i((label), (rs), (is))
#define jit_bner_l(label, s1, s2) jit_bner_i((label), (s1), (s2))
#define jit_bnei_l(label, rs, is) jit_bnei_i((label), (rs), (is))
#define jit_bmcr_l(label, s1, s2) jit_bmcr_i((label), (s1), (s2))
#define jit_bmci_l(label, rs, is) jit_bmci_i((label), (rs), (is))
#define jit_bmsr_l(label, s1, s2) jit_bmsr_i((label), (s1), (s2))
#define jit_bmsi_l(label, rs, is) jit_bmsi_i((label), (rs), (is))
#define jit_boaddr_l(label, s1, s2) jit_boaddr_i((label), (s1), (s2))
#define jit_boaddi_l(label, rs, is) jit_boaddi_i((label), (rs), (is))
#define jit_bosubr_l(label, s1, s2) jit_bosubr_i((label), (s1), (s2))
#define jit_bosubi_l(label, rs, is) jit_bosubi_i((label), (rs), (is))
#define jit_bltr_ul(label, s1, s2) jit_bltr_ui((label), (s1), (s2))
#define jit_blti_ul(label, rs, is) jit_blti_ui((label), (rs), (is))
#define jit_bler_ul(label, s1, s2) jit_bler_ui((label), (s1), (s2))
#define jit_blei_ul(label, rs, is) jit_blei_ui((label), (rs), (is))
#define jit_bgtr_ul(label, s1, s2) jit_bgtr_ui((label), (s1), (s2))
#define jit_bgti_ul(label, rs, is) jit_bgti_ui((label), (rs), (is))
#define jit_bger_ul(label, s1, s2) jit_bger_ui((label), (s1), (s2))
#define jit_bgei_ul(label, rs, is) jit_bgei_ui((label), (rs), (is))
#define jit_boaddr_ul(label, s1, s2) jit_boaddr_ui((label), (s1), (s2))
#define jit_boaddi_ul(label, rs, is) jit_boaddi_ui((label), (rs), (is))
#define jit_bosubr_ul(label, s1, s2) jit_bosubr_ui((label), (s1), (s2))
#define jit_bosubi_ul(label, rs, is) jit_bosubi_ui((label), (rs), (is))
#define jit_retval_l(rd) jit_retval_i((rd))
#endif
#endif /* __lightning_core_common_h_ */

View File

@@ -1,86 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer floating-point interface
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#define JIT_FPR0 JIT_FPR(0)
#define JIT_FPR1 JIT_FPR(1)
#define JIT_FPR2 JIT_FPR(2)
#define JIT_FPR3 JIT_FPR(3)
#define JIT_FPR4 JIT_FPR(4)
#define JIT_FPR5 JIT_FPR(5)
#ifdef JIT_RZERO
#ifndef jit_ldi_f
#define jit_ldi_f(rd, is) jit_ldxi_f((rd), JIT_RZERO, (is))
#define jit_sti_f(id, rs) jit_stxi_f((id), JIT_RZERO, (rs))
#define jit_ldi_d(rd, is) jit_ldxi_d((rd), JIT_RZERO, (is))
#define jit_sti_d(id, rs) jit_stxi_d((id), JIT_RZERO, (rs))
#endif
#ifndef jit_ldr_f
#define jit_ldr_f(rd, rs) jit_ldxr_f((rd), JIT_RZERO, (rs))
#define jit_str_f(rd, rs) jit_stxr_f((rd), JIT_RZERO, (rs))
#define jit_ldr_d(rd, rs) jit_ldxr_d((rd), JIT_RZERO, (rs))
#define jit_str_d(rd, rs) jit_stxr_d((rd), JIT_RZERO, (rs))
#endif
#endif
#ifndef jit_addr_f
#define jit_addr_f(rd,s1,s2) jit_addr_d(rd,s1,s2)
#define jit_subr_f(rd,s1,s2) jit_subr_d(rd,s1,s2)
#define jit_mulr_f(rd,s1,s2) jit_mulr_d(rd,s1,s2)
#define jit_divr_f(rd,s1,s2) jit_divr_d(rd,s1,s2)
#define jit_movr_f(rd,rs) jit_movr_d(rd,rs)
#define jit_abs_f(rd,rs) jit_abs_d(rd,rs)
#define jit_negr_f(rd,rs) jit_negr_d(rd,rs)
#define jit_sqrt_f(rd,rs) jit_sqrt_d(rd,rs)
#define jit_extr_f_d(rs, rd)
#define jit_extr_d_f(rs, rd)
#define jit_extr_i_f(rd, rs) jit_extr_i_d(rd, rs)
#define jit_roundr_f_i(rd, rs) jit_roundr_d_i(rd, rs)
#define jit_floorr_f_i(rd, rs) jit_floorr_d_i(rd, rs)
#define jit_ceilr_f_i(rd, rs) jit_ceilr_d_i(rd, rs)
#define jit_truncr_f_i(rd, rs) jit_truncr_d_i(rd, rs)
#define jit_ltr_f(d, s1, s2) jit_ltr_d(d, s1, s2)
#define jit_ler_f(d, s1, s2) jit_ler_d(d, s1, s2)
#define jit_eqr_f(d, s1, s2) jit_eqr_d(d, s1, s2)
#define jit_ner_f(d, s1, s2) jit_ner_d(d, s1, s2)
#define jit_ger_f(d, s1, s2) jit_ger_d(d, s1, s2)
#define jit_gtr_f(d, s1, s2) jit_gtr_d(d, s1, s2)
#define jit_unltr_f(d, s1, s2) jit_unltr_d(d, s1, s2)
#define jit_unler_f(d, s1, s2) jit_unler_d(d, s1, s2)
#define jit_uneqr_f(d, s1, s2) jit_uneqr_d(d, s1, s2)
#define jit_ltgtr_f(d, s1, s2) jit_ltgtr_d(d, s1, s2)
#define jit_unger_f(d, s1, s2) jit_unger_d(d, s1, s2)
#define jit_ungtr_f(d, s1, s2) jit_ungtr_d(d, s1, s2)
#define jit_ordr_f(d, s1, s2) jit_ordr_d(d, s1, s2)
#define jit_unordr_f(d, s1, s2) jit_unordr_d(d, s1, s2)
#define jit_retval_f(rs) jit_retval_d(rs)
#endif

View File

@@ -1,54 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer inline functions (common part)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_funcs_common_h
#define __lightning_funcs_common_h
#include <stdio.h>
#include <stdlib.h>
static int jit_fail(const char *, const char*, int, const char *) JIT_UNUSED;
int
jit_fail(const char *msg, const char *file, int line, const char *function)
{
fprintf(stderr, "%s: In function `%s':\n", file, function);
fprintf(stderr, "%s:%d: %s\n", file, line, msg);
abort();
}
#ifndef jit_start_pfx
#define jit_start_pfx() ( (jit_insn*)0x4)
#define jit_end_pfx() ( (jit_insn*)0x0)
#endif
#endif /* __lightning_funcs_common_h */

View File

@@ -1,125 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Run-time assembler for the i386
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2003 Gwenole Beauchesne
* Copyright 2006 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_asm_h
#define __lightning_asm_h
#ifndef LIGHTNING_DEBUG
/* OPCODE + i = immediate operand
* + r = register operand
* + m = memory operand (disp,base,index,scale)
* + sr/sm = a star preceding a register or memory
*/
#if !_ASM_SAFETY
# define _r1(R) _rN(R)
# define _r2(R) _rN(R)
# define _r4(R) _rN(R)
# define _r8(R) _rN(R)
# define _rM(R) _rN(R)
# define _rX(R) _rN(R)
#else
/* _r1() used to check only for _AL and _AH but there is
* usage of _CL and _DL when _*AX is already an operand */
# define _r1(R) \
/* Valid 32 bit register? */ \
((!((R) & ~0x77) \
/* 32, 16 or 8 bit register? */ \
&& (((_rC(R) == 0x40 || _rC(R) == 0x30 || _rC(R) == 0x10) \
/* Yes. Register is _AL, _CL or _DL? */ \
&& ( (_rN(R) | 0x10) == _AL \
|| (_rN(R) | 0x10) == _CL \
|| (_rN(R) | 0x10) == _DL)) \
/* No. Register is _AH? */ \
|| ((_rC(R) == 0x20 && (_rN(R) | 0x20) == _AH)))) \
? _rN(R) : JITFAIL("bad 8-bit register " #R))
# define _r2(R) \
/* Valid 32 bit register? */ \
((!((R) & ~0x77) \
/* 32, 16 or 8 bit register? */ \
&& (_rC(R) == 0x40 || _rC(R) == 0x30 || _rC(R) == 0x10)) \
? _rN(R) : JITFAIL("bad 16-bit register " #R))
# define _r4(R) \
/* Valid 32 bit register? */ \
((!((R) & ~0x77) \
/* 32, 16 or 8 bit register? */ \
&& (_rC(R) == 0x40 || _rC(R) == 0x30 || _rC(R) == 0x10)) \
? _rN(R) : JITFAIL("bad 32-bit register " #R))
# define _r8(R) \
JITFAIL("bad 64-bit register " #R)
# define _rM(R) \
/* Valid MMX register? */ \
((!((R) & ~0x67) && _rC(R) == 0x60) \
? _rN(R) : JITFAIL("bad MMX register " #R))
# define _rX(R) \
/* Valid SSE register? */ \
((!((R) & ~0x77) && _rC(R) == 0x70) \
? _rN(R) : JITFAIL("bad SSE register " #R))
#endif
#define _rA(R) _r4(R)
#define jit_check8(rs) ((_rN(rs) | _AL) == _AL)
#define jit_reg8(rs) \
((jit_reg16(rs) == _SI || jit_reg16(rs) == _DI) \
? _AL : (_rN(rs) | _AL))
#define jit_reg16(rs) (_rN(rs) | _AX)
/* Use RIP-addressing in 64-bit mode, if possible */
#define _r_X( R, D,B,I,S,O) (_r0P(I) ? (_r0P(B) ? _r_D (R,D ) : \
(_rsp12P(B) ? _r_DBIS(R,D,_ESP,_ESP,1) : \
_r_DB (R,D, B ))) : \
(_r0P(B) ? _r_4IS (R,D, I,S) : \
(!_rspP(I) ? _r_DBIS(R,D, B, I,S) : \
JITFAIL("illegal index register: %esp"))))
#define _m32only(X) (X)
#define _m64only(X) JITFAIL("invalid instruction in 32-bit mode")
#define _m64(X) ((void)0)
#define _AH 0x24
#define _CH 0x25
#define _DH 0x26
#define _BH 0x27
#define CALLsr(R) CALLLsr(R)
#define JMPsr(R) JMPLsr(R)
#define DECWr(RD) (_d16(), _Or (0x48,_r2(RD) ))
#define DECLr(RD) _Or (0x48,_r4(RD) )
#define INCWr(RD) (_d16(), _Or (0x40,_r2(RD) ))
#define INCLr(RD) _Or (0x40,_r4(RD) )
#endif
#endif /* __lightning_asm_h */

View File

@@ -1,430 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Run-time assembler for the x86-64
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2003 Gwenole Beauchesne
* Copyright 2006 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_asm_h
#define __lightning_asm_h
#ifndef LIGHTNING_DEBUG
/* OPCODE + i = immediate operand
* + r = register operand
* + m = memory operand (disp,base,index,scale)
* + sr/sm = a star preceding a register or memory
*/
#if !_ASM_SAFETY
# define _r1(R) _rN(R)
# define _r2(R) _rN(R)
# define _r4(R) _rN(R)
# define _r8(R) _rN(R)
# define _rM(R) _rN(R)
# define _rX(R) _rN(R)
#else
# define _r1(R) \
/* Valid 64 bit register? */ \
((!((R) & ~0xff) \
/* 64, 32, 16 or 8 bit register? */ \
&& (_rC(R) == 0x50 || _rC(R) == 0x40 \
|| _rC(R) == 0x30 || _rC(R) == 0x10)) \
? _rN(R) : JITFAIL("bad 8-bit register " #R))
# define _r2(R) \
/* Valid 64 bit register? */ \
((!((R) & ~0xff) \
/* 64, 32, 16 or 8 bit register? */ \
&& (_rC(R) == 0x50 || _rC(R) == 0x40 \
|| _rC(R) == 0x30 || _rC(R) == 0x10)) \
? _rN(R) : JITFAIL("bad 16-bit register " #R))
# define _r4(R) \
/* Valid 64 bit register? */ \
((!((R) & ~0xff) \
/* 64, 32, 16 or 8 bit register? */ \
&& (_rC(R) == 0x50 || _rC(R) == 0x40 \
|| _rC(R) == 0x30 || _rC(R) == 0x10)) \
? _rN(R) : JITFAIL("bad 32-bit register " #R))
# define _r8(R) \
/* Valid 64 bit register? */ \
((!((R) & ~0xff) \
/* 64, 32, 16 or 8 bit register? */ \
&& (_rC(R) == 0x50 || _rC(R) == 0x40 \
|| _rC(R) == 0x30 || _rC(R) == 0x10)) \
? _rN(R) : JITFAIL("bad 64-bit register " #R))
# define _rM(R) \
/* Valid MMX* register? */ \
((!((R) & ~0x6f) && _rC(R) == 0x60) \
? _rN(R) : JITFAIL("bad MMX register " #R))
# define _rX(R) \
/* Valid SSE2 register? */ \
((!((R) & ~0x7f) && _rC(R) == 0x70) \
? _rN(R) : JITFAIL("bad SSE2 register " #R))
#endif
#define _rA(R) _r8(R)
#define jit_check8(rs) 1
#define jit_reg8(rs) (_rR(rs) | _AL)
#define jit_reg16(rs) (_rR(rs) | _AX)
/* Use RIP-addressing in 64-bit mode, if possible */
#if 0
#define _x86_RIP_addressing_possible(D,O) (X86_RIP_RELATIVE_ADDR && \
((unsigned long)x86_get_target() + 4 + (O) - (D) <= 0xffffffff))
#define _r_X( R, D,B,I,S,O) (_r0P(I) ? (_r0P(B) ? (!X86_TARGET_64BIT ? _r_D(R,D) : \
(_x86_RIP_addressing_possible(D, O) ? \
_r_D(R, (D) - ((unsigned long)x86_get_target() + 4 + (O))) : \
_r_DSIB(R,D))) : \
_r_DSIB(R,D )) : \
(_rIP(B) ? _r_D (R,D ) : \
(_rsp12P(B) ? _r_DBIS(R,D,_RSP,_RSP,1) : \
_r_DB (R,D, B )))) : \
(_r0P(B) ? _r_4IS (R,D, I,S) : \
(!_rspP(I) ? _r_DBIS(R,D, B, I,S) : \
JITFAIL("illegal index register: %esp"))))
#else
#define _r_X( R, D,B,I,S,O) (_r0P(I) ? (_r0P(B) ? _r_DSIB(R,D ) : \
(_rIP(B) ? _r_D (R,D ) : \
(_rsp12P(B) ? _r_DBIS(R,D,_RSP,_RSP,1) : \
_r_DB (R,D, B )))) : \
(_r0P(B) ? _r_4IS (R,D, I,S) : \
(!_rspP(I) ? _r_DBIS(R,D, B, I,S) : \
JITFAIL("illegal index register: %esp"))))
#endif
#define _m32only(X) (JITFAIL("invalid instruction in 64-bit mode"))
#define _m64only(X) (X)
#define _m64(X) (X)
#define _SPL 0x14
#define _BPL 0x15
#define _SIL 0x16
#define _DIL 0x17
#define _R8B 0x18
#define _R9B 0x19
#define _R10B 0x1A
#define _R11B 0x1B
#define _R12B 0x1C
#define _R13B 0x1D
#define _R14B 0x1E
#define _R15B 0x1F
#define _R8W 0x38
#define _R9W 0x39
#define _R10W 0x3A
#define _R11W 0x3B
#define _R12W 0x3C
#define _R13W 0x3D
#define _R14W 0x3E
#define _R15W 0x3F
#define _R8D 0x48
#define _R9D 0x49
#define _R10D 0x4A
#define _R11D 0x4B
#define _R12D 0x4C
#define _R13D 0x4D
#define _R14D 0x4E
#define _R15D 0x4F
#define _RAX 0x50
#define _RCX 0x51
#define _RDX 0x52
#define _RBX 0x53
#define _RSP 0x54
#define _RBP 0x55
#define _RSI 0x56
#define _RDI 0x57
#define _R8 0x58
#define _R9 0x59
#define _R10 0x5A
#define _R11 0x5B
#define _R12 0x5C
#define _R13 0x5D
#define _R14 0x5E
#define _R15 0x5F
#define _RIP -2
#define _r1e8lP(R) ((int)(R) >= _SPL && (int)(R) <= _DIL)
#define DECWr(RD) (_d16(), _REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r2(RD) ))
#define DECLr(RD) (_REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r4(RD) ))
#define INCWr(RD) (_d16(), _REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r2(RD) ))
#define INCLr(RD) (_REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r4(RD) ))
#define ADCQrr(RS, RD) _ALUQrr(X86_ADC, RS, RD)
#define ADCQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_ADC, MD, MB, MI, MS, RD)
#define ADCQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_ADC, RS, MD, MB, MI, MS)
#define ADCQir(IM, RD) _ALUQir(X86_ADC, IM, RD)
#define ADCQim(IM, MD, MB, MI, MS) _ALUQim(X86_ADC, IM, MD, MB, MI, MS)
#define ADDQrr(RS, RD) _ALUQrr(X86_ADD, RS, RD)
#define ADDQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_ADD, MD, MB, MI, MS, RD)
#define ADDQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_ADD, RS, MD, MB, MI, MS)
#define ADDQir(IM, RD) _ALUQir(X86_ADD, IM, RD)
#define ADDQim(IM, MD, MB, MI, MS) _ALUQim(X86_ADD, IM, MD, MB, MI, MS)
#define ANDQrr(RS, RD) _ALUQrr(X86_AND, RS, RD)
#define ANDQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_AND, MD, MB, MI, MS, RD)
#define ANDQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_AND, RS, MD, MB, MI, MS)
#define ANDQir(IM, RD) _ALUQir(X86_AND, IM, RD)
#define ANDQim(IM, MD, MB, MI, MS) _ALUQim(X86_AND, IM, MD, MB, MI, MS)
#define CMPQrr(RS, RD) _ALUQrr(X86_CMP, RS, RD)
#define CMPQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_CMP, MD, MB, MI, MS, RD)
#define CMPQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_CMP, RS, MD, MB, MI, MS)
#define CMPQir(IM, RD) _ALUQir(X86_CMP, IM, RD)
#define CMPQim(IM, MD, MB, MI, MS) _ALUQim(X86_CMP, IM, MD, MB, MI, MS)
#define ORQrr(RS, RD) _ALUQrr(X86_OR, RS, RD)
#define ORQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_OR, MD, MB, MI, MS, RD)
#define ORQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_OR, RS, MD, MB, MI, MS)
#define ORQir(IM, RD) _ALUQir(X86_OR, IM, RD)
#define ORQim(IM, MD, MB, MI, MS) _ALUQim(X86_OR, IM, MD, MB, MI, MS)
#define SBBQrr(RS, RD) _ALUQrr(X86_SBB, RS, RD)
#define SBBQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_SBB, MD, MB, MI, MS, RD)
#define SBBQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_SBB, RS, MD, MB, MI, MS)
#define SBBQir(IM, RD) _ALUQir(X86_SBB, IM, RD)
#define SBBQim(IM, MD, MB, MI, MS) _ALUQim(X86_SBB, IM, MD, MB, MI, MS)
#define SUBQrr(RS, RD) _ALUQrr(X86_SUB, RS, RD)
#define SUBQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_SUB, MD, MB, MI, MS, RD)
#define SUBQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_SUB, RS, MD, MB, MI, MS)
#define SUBQir(IM, RD) _ALUQir(X86_SUB, IM, RD)
#define SUBQim(IM, MD, MB, MI, MS) _ALUQim(X86_SUB, IM, MD, MB, MI, MS)
#define XORQrr(RS, RD) _ALUQrr(X86_XOR, RS, RD)
#define XORQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_XOR, MD, MB, MI, MS, RD)
#define XORQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_XOR, RS, MD, MB, MI, MS)
#define XORQir(IM, RD) _ALUQir(X86_XOR, IM, RD)
#define XORQim(IM, MD, MB, MI, MS) _ALUQim(X86_XOR, IM, MD, MB, MI, MS)
#define ROLQir(IM, RD) _ROTSHIQir(X86_ROL, IM, RD)
#define ROLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_ROL, IM, MD, MB, MI, MS)
#define ROLQrr(RS, RD) _ROTSHIQrr(X86_ROL, RS, RD)
#define ROLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_ROL, RS, MD, MB, MI, MS)
#define RORQir(IM, RD) _ROTSHIQir(X86_ROR, IM, RD)
#define RORQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_ROR, IM, MD, MB, MI, MS)
#define RORQrr(RS, RD) _ROTSHIQrr(X86_ROR, RS, RD)
#define RORQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_ROR, RS, MD, MB, MI, MS)
#define RCLQir(IM, RD) _ROTSHIQir(X86_RCL, IM, RD)
#define RCLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_RCL, IM, MD, MB, MI, MS)
#define RCLQrr(RS, RD) _ROTSHIQrr(X86_RCL, RS, RD)
#define RCLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_RCL, RS, MD, MB, MI, MS)
#define RCRQir(IM, RD) _ROTSHIQir(X86_RCR, IM, RD)
#define RCRQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_RCR, IM, MD, MB, MI, MS)
#define RCRQrr(RS, RD) _ROTSHIQrr(X86_RCR, RS, RD)
#define RCRQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_RCR, RS, MD, MB, MI, MS)
#define SHLQir(IM, RD) _ROTSHIQir(X86_SHL, IM, RD)
#define SHLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SHL, IM, MD, MB, MI, MS)
#define SHLQrr(RS, RD) _ROTSHIQrr(X86_SHL, RS, RD)
#define SHLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SHL, RS, MD, MB, MI, MS)
#define SHRQir(IM, RD) _ROTSHIQir(X86_SHR, IM, RD)
#define SHRQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SHR, IM, MD, MB, MI, MS)
#define SHRQrr(RS, RD) _ROTSHIQrr(X86_SHR, RS, RD)
#define SHRQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SHR, RS, MD, MB, MI, MS)
#define SALQir SHLQir
#define SALQim SHLQim
#define SALQrr SHLQrr
#define SALQrm SHLQrm
#define SARQir(IM, RD) _ROTSHIQir(X86_SAR, IM, RD)
#define SARQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SAR, IM, MD, MB, MI, MS)
#define SARQrr(RS, RD) _ROTSHIQrr(X86_SAR, RS, RD)
#define SARQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SAR, RS, MD, MB, MI, MS)
#define BTQir(IM, RD) _BTQir(X86_BT, IM, RD)
#define BTQim(IM, MD, MB, MI, MS) _BTQim(X86_BT, IM, MD, MB, MI, MS)
#define BTQrr(RS, RD) _BTQrr(X86_BT, RS, RD)
#define BTQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BT, RS, MD, MB, MI, MS)
#define BTCQir(IM, RD) _BTQir(X86_BTC, IM, RD)
#define BTCQim(IM, MD, MB, MI, MS) _BTQim(X86_BTC, IM, MD, MB, MI, MS)
#define BTCQrr(RS, RD) _BTQrr(X86_BTC, RS, RD)
#define BTCQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTC, RS, MD, MB, MI, MS)
#define BTRQir(IM, RD) _BTQir(X86_BTR, IM, RD)
#define BTRQim(IM, MD, MB, MI, MS) _BTQim(X86_BTR, IM, MD, MB, MI, MS)
#define BTRQrr(RS, RD) _BTQrr(X86_BTR, RS, RD)
#define BTRQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTR, RS, MD, MB, MI, MS)
#define BTSQir(IM, RD) _BTQir(X86_BTS, IM, RD)
#define BTSQim(IM, MD, MB, MI, MS) _BTQim(X86_BTS, IM, MD, MB, MI, MS)
#define BTSQrr(RS, RD) _BTQrr(X86_BTS, RS, RD)
#define BTSQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTS, RS, MD, MB, MI, MS)
#define LEAQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (0x8d ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x89 ,_b11,_r8(RS),_r8(RD) ))
#define MOVQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (0x8b ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x89 ,_r8(RS) ,MD,MB,MI,MS ))
#define MOVQir(IM, R) (_REXQrr(0, R), _Or_Q (0xb8,_r8(R) ,IM ))
#define MOVQim(IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_X_L (0xc7 ,MD,MB,MI,MS ,IM ))
#define NOTQr(RS) _UNARYQr(X86_NOT, RS)
#define NOTQm(MD, MB, MI, MS) _UNARYQm(X86_NOT, MD, MB, MI, MS)
#define NEGQr(RS) _UNARYQr(X86_NEG, RS)
#define NEGQm(MD, MB, MI, MS) _UNARYQm(X86_NEG, MD, MB, MI, MS)
#define MULQr(RS) _UNARYQr(X86_MUL, RS)
#define MULQm(MD, MB, MI, MS) _UNARYQm(X86_MUL, MD, MB, MI, MS)
#define IMULQr(RS) _UNARYQr(X86_IMUL, RS)
#define IMULQm(MD, MB, MI, MS) _UNARYQm(X86_IMUL, MD, MB, MI, MS)
#define DIVQr(RS) _UNARYQr(X86_DIV, RS)
#define DIVQm(MD, MB, MI, MS) _UNARYQm(X86_DIV, MD, MB, MI, MS)
#define IDIVQr(RS) _UNARYQr(X86_IDIV, RS)
#define IDIVQm(MD, MB, MI, MS) _UNARYQm(X86_IDIV, MD, MB, MI, MS)
#define IMULQir(IM, RD) IMULQirr(IM, RD, RD)
#define IMULQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r8(RD),_r8(RS) ))
#define IMULQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0faf ,_r8(RD) ,MD,MB,MI,MS ))
#define IMULQirr(IM,RS,RD) (_REXQrr(RD, RS), _Os_Mrm_sL (0x69 ,_b11,_r8(RS),_r8(RD) ,IM ))
#define IMULQimr(IM,MD,MB,MI,MS,RD) (_REXQmr(MB, MI, RD), _Os_r_X_sL (0x69 ,_r8(RD) ,MD,MB,MI,MS ,IM ))
#define CALLQsr(R) (_REXQrr(0, R), _O_Mrm (0xff ,_b11,_b010,_r8(R) ))
#define JMPQsr(R) (_REXQrr(0, R), _O_Mrm (0xff ,_b11,_b100,_r8(R) ))
#define CMOVQrr(CC,RS,RD) (_REXQrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r8(RD),_r8(RS) ))
#define CMOVQmr(CC,MD,MB,MI,MS,RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r8(RD) ,MD,MB,MI,MS ))
#define POPQr(RD) _m64only((_REXQr(RD), _Or (0x58,_r8(RD) )))
#define POPQm(MD, MB, MI, MS) _m64only((_REXQm(MB, MI), _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS )))
#define PUSHQr(RS) _m64only((_REXQr(RS), _Or (0x50,_r8(RS) )))
#define PUSHQm(MD, MB, MI, MS) _m64only((_REXQm(MB, MI), _O_r_X (0xff ,_b110 ,MD,MB,MI,MS )))
#define PUSHQi(IM) _m64only( _Os_sL (0x68 ,IM ))
#define TESTQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x85 ,_b11,_r8(RS),_r8(RD) ))
#define TESTQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x85 ,_r8(RS) ,MD,MB,MI,MS ))
#define TESTQir(IM, RD) \
/* Immediate fits in 32 bits? */ \
(_s32P((long)(IM)) \
/* Yes. Immediate does not fit in 8 bits and reg is %rax? */ \
? (!_s8P(IM) && (RD) == _RAX \
? (_REXQrr(0, RD), _O_L(0xa9, IM)) \
: (_REXQrr(0, RD), _O_Mrm_L(0xf7, _b11, _b000, _r8(RD), IM))) \
/* No. Need immediate in a register */ \
: (MOVQir(IM, JIT_REXTMP), TESTQrr(JIT_REXTMP, RD)))
#define TESTQim(IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X_L (0xf7 ,_b000 ,MD,MB,MI,MS ,IM ))
#define CMPXCHGQrr(RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r8(RS),_r8(RD) ))
#define CMPXCHGQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r8(RS) ,MD,MB,MI,MS ))
#define XADDQrr(RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r8(RS),_r8(RD) ))
#define XADDQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r8(RS) ,MD,MB,MI,MS ))
#define XCHGQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x87 ,_b11,_r8(RS),_r8(RD) ))
#define XCHGQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x87 ,_r8(RS) ,MD,MB,MI,MS ))
#define DECQm(MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS ))
#define DECQr(RD) (_REXQrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r8(RD) ))
#define INCQm(MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS ))
#define INCQr(RD) (_REXQrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r8(RD) ))
#define BSFQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r8(RD),_r8(RS) ))
#define BSFQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r8(RD) ,MD,MB,MI,MS ))
#define BSRQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r8(RD),_r8(RS) ))
#define BSRQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVSBQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r8(RD),_r1(RS) ))
#define MOVSBQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVZBQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r8(RD),_r1(RS) ))
#define MOVZBQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVSWQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbf ,_b11,_r8(RD),_r2(RS) ))
#define MOVSWQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbf ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVZWQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fb7 ,_b11,_r8(RD),_r2(RS) ))
#define MOVZWQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fb7 ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVSLQrr(RS, RD) _m64only((_REXQrr(RD, RS), _O_Mrm (0x63 ,_b11,_r8(RD),_r4(RS) )))
#define MOVSLQmr(MD, MB, MI, MS, RD) _m64only((_REXQmr(MB, MI, RD), _O_r_X (0x63 ,_r8(RD) ,MD,MB,MI,MS )))
#define BSWAPQr(R) (_REXQrr(0, R), _OOr (0x0fc8,_r8(R) ))
#define __SSEQrr(OP,RS,RSA,RD,RDA) (_REXQrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) ))
#define __SSEQmr(OP,MD,MB,MI,MS,RD,RDA) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS ))
#define __SSEQrm(OP,RS,RSA,MD,MB,MI,MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS ))
#define __SSEQ1rm(OP,RS,RSA,MD,MB,MI,MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f01|(OP) ,RSA(RS) ,MD,MB,MI,MS ))
#define _SSEQrr(PX,OP,RS,RSA,RD,RDA) (_jit_B(PX), __SSEQrr(OP, RS, RSA, RD, RDA))
#define _SSEQmr(PX,OP,MD,MB,MI,MS,RD,RDA) (_jit_B(PX), __SSEQmr(OP, MD, MB, MI, MS, RD, RDA))
#define _SSEQrm(PX,OP,RS,RSA,MD,MB,MI,MS) (_jit_B(PX), __SSEQrm(OP, RS, RSA, MD, MB, MI, MS))
#define _SSEQ1rm(PX,OP,RS,RSA,MD,MB,MI,MS) (_jit_B(PX), __SSEQ1rm(OP, RS, RSA, MD, MB, MI, MS))
#define CVTTSS2SIQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTTSI, RS,_rX, RD,_r8)
#define CVTTSS2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTTSI, MD, MB, MI, MS, RD,_r8)
#define CVTTSD2SIQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTTSI, RS,_rX, RD,_r8)
#define CVTTSD2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTTSI, MD, MB, MI, MS, RD,_r8)
#define CVTSS2SIQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTSI, RS,_rX, RD,_r8)
#define CVTSS2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTSI, MD, MB, MI, MS, RD,_r8)
#define CVTSD2SIQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTSI, RS,_rX, RD,_r8)
#define CVTSD2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTSI, MD, MB, MI, MS, RD,_r8)
#define CVTSI2SSQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTIS, RS,_r8, RD,_rX)
#define CVTSI2SSQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTIS, MD, MB, MI, MS, RD,_rX)
#define CVTSI2SDQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTIS, RS,_r8, RD,_rX)
#define CVTSI2SDQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTIS, MD, MB, MI, MS, RD,_rX)
#define MOVDQXrr(RS, RD) _SSEQrr(0x66, 0x6e, RS,_r8, RD,_rX)
#define MOVDQXmr(MD, MB, MI, MS, RD) _SSEQmr(0x66, 0x6e, MD, MB, MI, MS, RD,_rX)
#define MOVDXQrr(RS, RD) _SSEQrr(0x66, 0x7e, RS,_rX, RD,_r8)
#define MOVDXQrm(RS, MD, MB, MI, MS) _SSEQrm(0x66, 0x7e, RS,_rX, MD, MB, MI, MS)
#define MOVDQMrr(RS, RD) __SSEQrr( 0x6e, RS,_r8, RD,_rM)
#define MOVDQMmr(MD, MB, MI, MS, RD) __SSEQmr( 0x6e, MD, MB, MI, MS, RD,_rM)
#define MOVDMQrr(RS, RD) __SSEQrr( 0x7e, RS,_rM, RD,_r8)
#define MOVDMQrm(RS, MD, MB, MI, MS) __SSEQrm( 0x7e, RS,_rM, MD, MB, MI, MS)
#define CALLsr(R) CALLQsr(R)
#define JMPsr(R) JMPQsr(R)
#endif
#endif /* __lightning_asm_h */

File diff suppressed because it is too large Load Diff

View File

@@ -1,177 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer (i386 version)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
* Written by Paolo Bonzini and Matthew Flatt.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_core_h
#define __lightning_core_h
#define JIT_CAN_16 1
#define JIT_AP _EBP
#define JIT_R_NUM 3
#define JIT_R(i) (_EAX + (i))
#define JIT_V_NUM 3
#define JIT_V(i) ((i) == 0 ? _EBX : _ESI + (i) - 1)
struct jit_local_state {
int framesize;
int argssize;
int alloca_offset;
int alloca_slack;
jit_insn *finish_ref;
};
/* Whether a register is used for the user-accessible registers. */
#define jit_save(reg) 1
#define jit_base_prolog() (_jitl.framesize = 20, _jitl.alloca_offset = _jitl.alloca_slack = 0, _jitl.argssize = 0, \
PUSHLr(_EBX), PUSHLr(_ESI), PUSHLr(_EDI), PUSHLr(_EBP), MOVLrr(_ESP, _EBP))
#define jit_base_ret(ofs) \
(((ofs) < 0 ? LEAVE_() : POPLr(_EBP)), \
POPLr(_EDI), POPLr(_ESI), POPLr(_EBX), RET_())
/* Used internally. SLACK is used by the Darwin ABI which keeps the stack
aligned to 16-bytes. */
#define jit_allocai_internal(amount, slack) \
(((amount) < _jitl.alloca_slack \
? (void)0 \
: (void)(_jitl.alloca_slack += (amount) + (slack), \
((amount) + (slack) == sizeof (int) \
? PUSHLr(_EAX) \
: SUBLir((amount) + (slack), _ESP)))), \
_jitl.alloca_slack -= (amount), \
_jitl.alloca_offset -= (amount))
/* Stack */
#define jit_pushr_i(rs) PUSHLr(rs)
#define jit_popr_i(rs) POPLr(rs)
/* The += in argssize allows for stack pollution */
#ifdef __APPLE__
/* Stack must stay 16-byte aligned: */
# define jit_prepare_i(ni) (((ni & 0x3) \
? (void)SUBLir(4 * ((((ni) + 3) & ~(0x3)) - (ni)), JIT_SP) \
: (void)0), \
_jitl.argssize += (((ni) + 3) & ~(0x3)))
#define jit_allocai(n) \
jit_allocai_internal ((n), (_jitl.alloca_slack - (n)) & 15)
#define jit_prolog(n) (jit_base_prolog(), jit_subi_i (JIT_SP, JIT_SP, 12))
#define jit_ret() jit_base_ret (-12)
#else
# define jit_prepare_i(ni) (_jitl.argssize += (ni))
#define jit_allocai(n) \
jit_allocai_internal ((n), 0)
#define jit_prolog(n) jit_base_prolog()
#define jit_ret() jit_base_ret (_jitl.alloca_offset)
#endif
#define jit_bare_ret() RET_()
#define jit_calli(label) (CALLm( ((unsigned long) (label))), _jit.x.pc)
#define jit_callr(reg) CALLsr(reg)
#define jit_pusharg_i(rs) PUSHLr(rs)
#define jit_finish(sub) (_jitl.finish_ref = jit_calli((sub)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0, _jitl.finish_ref)
#define jit_finishr(reg) (jit_callr((reg)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0)
#define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_s() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_us() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_i() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_ui() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_l() ((_jitl.framesize += sizeof(long)) - sizeof(long))
#define jit_arg_ul() ((_jitl.framesize += sizeof(long)) - sizeof(long))
#define jit_arg_p() ((_jitl.framesize += sizeof(long)) - sizeof(long))
#define jit_movi_p(d, is) (MOVLir (((long)(is)), (d)), _jit.x.pc)
#define jit_patch_long_at(jump_pc,v) (*_PSL((jump_pc) - sizeof(long)) = _jit_SL((jit_insn *)(v) - (jump_pc)))
#define jit_patch_at(jump_pc,v) jit_patch_long_at(jump_pc, v)
#define jit_patch_calli(jump_pc,v) jit_patch_long_at(jump_pc, v)
/* Memory */
#define jit_replace(s, rep, op) \
(jit_pushr_i(rep), \
MOVLrr((s), (rep)), \
op, jit_popr_i(rep))
#define jit_movbrm(rs, dd, db, di, ds) \
(jit_check8(rs) \
? MOVBrm(jit_reg8(rs), dd, db, di, ds) \
: jit_replace(rs, \
((dd != _EAX && db != _EAX && di != _EAX) ? _EAX : \
((dd != _ECX && db != _ECX && di != _ECX) ? _ECX : _EDX)), \
MOVBrm(((dd != _EAX && db != _EAX && di != _EAX) ? _AL : \
((dd != _ECX && db != _ECX && di != _ECX) ? _CL : _DL)), \
dd, db, di, ds)))
#define jit_ldr_c(d, rs) MOVSBLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_c(d, s1, s2) MOVSBLmr(0, (s1), (s2), 1, (d))
#define jit_ldr_s(d, rs) MOVSWLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_s(d, s1, s2) MOVSWLmr(0, (s1), (s2), 1, (d))
#define jit_ldi_c(d, is) MOVSBLmr((is), 0, 0, 0, (d))
#define jit_ldxi_c(d, rs, is) MOVSBLmr((is), (rs), 0, 0, (d))
#define jit_ldi_uc(d, is) MOVZBLmr((is), 0, 0, 0, (d))
#define jit_ldxi_uc(d, rs, is) MOVZBLmr((is), (rs), 0, 0, (d))
#define jit_sti_c(id, rs) jit_movbrm((rs), (id), 0, 0, 0)
#define jit_stxi_c(id, rd, rs) jit_movbrm((rs), (id), (rd), 0, 0)
#define jit_ldi_s(d, is) MOVSWLmr((is), 0, 0, 0, (d))
#define jit_ldxi_s(d, rs, is) MOVSWLmr((is), (rs), 0, 0, (d))
#define jit_ldi_us(d, is) MOVZWLmr((is), 0, 0, 0, (d))
#define jit_ldxi_us(d, rs, is) MOVZWLmr((is), (rs), 0, 0, (d))
#define jit_sti_s(id, rs) MOVWrm(jit_reg16(rs), (id), 0, 0, 0)
#define jit_stxi_s(id, rd, rs) MOVWrm(jit_reg16(rs), (id), (rd), 0, 0)
#define jit_ldi_i(d, is) MOVLmr((is), 0, 0, 0, (d))
#define jit_ldxi_i(d, rs, is) MOVLmr((is), (rs), 0, 0, (d))
#define jit_ldr_i(d, rs) MOVLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_i(d, s1, s2) MOVLmr(0, (s1), (s2), 1, (d))
#define jit_sti_i(id, rs) MOVLrm((rs), (id), 0, 0, 0)
#define jit_stxi_i(id, rd, rs) MOVLrm((rs), (id), (rd), 0, 0)
#endif /* __lightning_core_h */

View File

@@ -1,499 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer (i386 version)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
* Written by Paolo Bonzini and Matthew Flatt.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_core_h
#define __lightning_core_h
/* Used to implement ldc, stc, ... */
#define JIT_CAN_16 0
#define JIT_REXTMP _R12
/* Number or integer argument registers */
#define JIT_ARG_MAX 6
/* Number of float argument registers */
#define JIT_FP_ARG_MAX 8
#define JIT_R_NUM 3
#define JIT_R(i) ((i) == 0 ? _EAX : _R9 + (i))
#define JIT_V_NUM 3
#define JIT_V(i) ((i) == 0 ? _EBX : _R12 + (i))
struct jit_local_state {
int long_jumps;
int nextarg_getfp;
int nextarg_putfp;
int nextarg_geti;
int nextarg_puti;
int framesize;
int argssize;
int fprssize;
int alloca_offset;
int alloca_slack;
jit_insn *finish_ref;
};
/* Whether a register in the "low" bank is used for the user-accessible
registers. */
#define jit_save(reg) ((reg) == _EAX || (reg) == _EBX)
/* Keep the stack 16-byte aligned, the SSE hardware prefers it this way. */
#define jit_allocai_internal(amount, slack) \
(((amount) < _jitl.alloca_slack \
? 0 \
: (_jitl.alloca_slack += (amount) + (slack), \
SUBQir((amount) + (slack), _ESP))), \
_jitl.alloca_slack -= (amount), \
_jitl.alloca_offset -= (amount))
#define jit_allocai(n) \
jit_allocai_internal ((n), (_jitl.alloca_slack - (n)) & 15)
/* 3-parameter operation */
#define jit_qopr_(d, s1, s2, op1d, op2d) \
( ((s2) == (d)) ? op1d : \
( (((s1) == (d)) ? (void)0 : (void)MOVQrr((s1), (d))), op2d ) \
)
/* 3-parameter operation, with immediate. TODO: fix the case where mmediate
does not fit! */
#define jit_qop_small(d, s1, op2d) \
(((s1) == (d)) ? op2d : (MOVQrr((s1), (d)), op2d))
#define jit_qop_(d, s1, is, op2d, op2i) \
(_s32P((long)(is)) \
? jit_qop_small ((d), (s1), (op2d)) \
: (MOVQir ((is), JIT_REXTMP), jit_qop_small ((d), (s1), (op2i))))
#define jit_bra_qr(s1, s2, op) (CMPQrr(s2, s1), op, _jit.x.pc)
#define _jit_bra_l(rs, is, op) (CMPQir(is, rs), op, _jit.x.pc)
#define jit_bra_l(rs, is, op) (_s32P((long)(is)) \
? _jit_bra_l(rs, is, op) \
: (MOVQir(is, JIT_REXTMP), jit_bra_qr(rs, JIT_REXTMP, op)))
/* When CMP with 0 can be replaced with TEST */
#define jit_bra_l0(rs, is, op, op0) \
( (is) == 0 ? (TESTQrr(rs, rs), op0, _jit.x.pc) : jit_bra_l(rs, is, op))
#define jit_reduceQ(op, is, rs) \
(_u8P(is) ? jit_reduce_(op##Bir(is, jit_reg8(rs))) : \
jit_reduce_(op##Qir(is, rs)) )
#define jit_addi_l(d, rs, is) \
/* Value is not zero? */ \
((is) \
/* Yes. Value is unsigned and fits in signed 32 bits? */ \
? (_uiP(31, is) \
/* Yes. d == rs? */ \
? jit_opi_((d), (rs), \
/* Yes. Use add opcode */ \
ADDQir((is), (d)), \
/* No. Use lea opcode */ \
LEAQmr((is), (rs), 0, 0, (d))) \
/* No. Need value in a register */ \
: (jit_movi_l(JIT_REXTMP, is), \
jit_addr_l(d, rs, JIT_REXTMP))) \
: jit_opi_((d),(rs),0,jit_movr_l(d, rs)))
#define jit_addr_l(d, s1, s2) jit_opo_((d), (s1), (s2), ADDQrr((s2), (d)), ADDQrr((s1), (d)), LEAQmr(0, (s1), (s2), 1, (d)) )
#define jit_addci_l(d, rs, is) jit_qop_ ((d), (rs), (is), ADCQir((is), (d)), ADCQrr(JIT_REXTMP, (d)))
#define jit_addcr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), ADCQrr((s1), (d)), ADCQrr((s2), (d)) )
#define jit_addxi_l(d, rs, is) jit_qop_ ((d), (rs), (is), ADDQir((is), (d)), ADDQrr(JIT_REXTMP, (d)))
#define jit_addxr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), ADDQrr((s1), (d)), ADDQrr((s2), (d)) )
#define jit_andi_l(d, rs, is) jit_qop_ ((d), (rs), (is), ANDQir((is), (d)), ANDQrr(JIT_REXTMP, (d)))
#define jit_andr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), ANDQrr((s1), (d)), ANDQrr((s2), (d)) )
#define jit_orr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), ORQrr((s1), (d)), ORQrr((s2), (d)) )
#define jit_subr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), (SUBQrr((s1), (d)), NEGQr(d)), SUBQrr((s2), (d)) )
#define jit_xorr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), XORQrr((s1), (d)), XORQrr((s2), (d)) )
/* These can sometimes use byte or word versions! */
#define jit_ori_l(d, rs, is) jit_qop_ ((d), (rs), (is), jit_reduceQ(OR, (is), (d)), ORQrr(JIT_REXTMP, (d)) )
#define jit_xori_l(d, rs, is) jit_qop_ ((d), (rs), (is), jit_reduceQ(XOR, (is), (d)), XORQrr(JIT_REXTMP, (d)) )
#define jit_lshi_l(d, rs, is) ((is) <= 3 ? LEAQmr(0, 0, (rs), 1 << (is), (d)) : jit_qop_small ((d), (rs), SHLQir((is), (d)) ))
#define jit_rshi_l(d, rs, is) jit_qop_small ((d), (rs), SARQir((is), (d)) )
#define jit_rshi_ul(d, rs, is) jit_qop_small ((d), (rs), SHRQir((is), (d)) )
#define jit_lshr_l(d, r1, r2) jit_shift((d), (r1), (r2), SHLQrr)
#define jit_rshr_l(d, r1, r2) jit_shift((d), (r1), (r2), SARQrr)
#define jit_rshr_ul(d, r1, r2) jit_shift((d), (r1), (r2), SHRQrr)
/* Stack */
#define jit_pushr_i(rs) PUSHQr(rs)
#define jit_popr_i(rs) POPQr(rs)
/* A return address is 8 bytes, plus 5 registers = 40 bytes, total = 48 bytes. */
#define jit_prolog(n) (_jitl.framesize = ((n) & 1) ? 56 : 48, _jitl.nextarg_getfp = _jitl.nextarg_geti = 0, _jitl.alloca_offset = 0, \
PUSHQr(_EBX), PUSHQr(_R12), PUSHQr(_R13), PUSHQr(_R14), PUSHQr(_EBP), MOVQrr(_ESP, _EBP))
#define jit_calli(sub) (MOVQir((long) (sub), JIT_REXTMP), _jitl.finish_ref = _jit.x.pc, CALLsr(JIT_REXTMP), _jitl.finish_ref)
#define jit_callr(reg) CALLsr((reg))
#define jit_prepare_i(ni) (_jitl.nextarg_puti = (ni), \
_jitl.argssize = _jitl.nextarg_puti > JIT_ARG_MAX \
? _jitl.nextarg_puti - JIT_ARG_MAX : 0)
#define jit_pusharg_i(rs) (--_jitl.nextarg_puti >= JIT_ARG_MAX \
? PUSHQr(rs) : MOVQrr(rs, jit_arg_reg_order[_jitl.nextarg_puti]))
#define jit_finish(sub) (_jitl.fprssize \
? (MOVBir(_jitl.fprssize, _AL), _jitl.fprssize = 0) \
: MOVBir(0, _AL), \
((_jitl.argssize & 1) \
? (PUSHQr(_EAX), ++_jitl.argssize) : 0), \
jit_calli(sub), \
(_jitl.argssize \
? (ADDQir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0) \
: 0), \
_jitl.finish_ref)
#define jit_reg_is_arg(reg) ((reg) == _ECX || (reg) == _EDX)
#define jit_finishr(reg) (_jitl.fprssize \
? (MOVBir(_jitl.fprssize, _AL), _jitl.fprssize = 0) \
: MOVBir(0, _AL), \
((_jitl.argssize & 1) \
? (PUSHQr(_EAX), ++_jitl.argssize) : 0), \
(jit_reg_is_arg((reg)) \
? (MOVQrr(reg, JIT_REXTMP), \
jit_callr(JIT_REXTMP)) \
: jit_callr(reg)), \
(_jitl.argssize \
? (ADDQir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0) \
: 0))
#define jit_retval_l(rd) ((void)jit_movr_l ((rd), _EAX))
#define jit_arg_i() (_jitl.nextarg_geti < JIT_ARG_MAX \
? _jitl.nextarg_geti++ \
: (int) ((_jitl.framesize += sizeof(long)) - sizeof(long)))
#define jit_arg_c() jit_arg_i()
#define jit_arg_uc() jit_arg_i()
#define jit_arg_s() jit_arg_i()
#define jit_arg_us() jit_arg_i()
#define jit_arg_ui() jit_arg_i()
#define jit_arg_l() jit_arg_i()
#define jit_arg_ul() jit_arg_i()
#define jit_arg_p() jit_arg_i()
#define jit_getarg_c(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_extr_c_l((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_c((reg), JIT_FP, (ofs)))
#define jit_getarg_uc(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_extr_uc_ul((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_uc((reg), JIT_FP, (ofs)))
#define jit_getarg_s(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_extr_s_l((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_s((reg), JIT_FP, (ofs)))
#define jit_getarg_us(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_extr_us_ul((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_us((reg), JIT_FP, (ofs)))
#define jit_getarg_i(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_movr_l((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_i((reg), JIT_FP, (ofs)))
#define jit_getarg_ui(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_movr_ul((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_ui((reg), JIT_FP, (ofs)))
#define jit_getarg_l(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_movr_l((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_l((reg), JIT_FP, (ofs)))
#define jit_getarg_ul(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_movr_ul((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_ul((reg), JIT_FP, ofs))
#define jit_getarg_p(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_movr_p((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_p((reg), JIT_FP, (ofs)))
static int jit_arg_reg_order[] = { _EDI, _ESI, _EDX, _ECX, _R8D, _R9D };
#define jit_negr_l(d, rs) jit_opi_((d), (rs), NEGQr(d), (XORQrr((d), (d)), SUBQrr((rs), (d))) )
#define jit_movr_l(d, rs) ((void)((rs) == (d) ? 0 : MOVQrr((rs), (d))))
#define jit_movi_p(d, is) (MOVQir(((long)(is)), (d)), _jit.x.pc)
#define jit_movi_l(d, is) \
/* Value is not zero? */ \
((is) \
/* Yes. Value is unsigned and fits in signed 32 bits? */ \
? (_uiP(31, is) \
/* Yes. Use 32 bits opcode */ \
? MOVLir(is, (d)) \
/* No. Use 64 bits opcode */ \
: MOVQir(is, (d))) \
/* No. Set register to zero. */ \
: XORQrr ((d), (d)))
#define jit_bmsr_l(label, s1, s2) (TESTQrr((s1), (s2)), JNZm(label), _jit.x.pc)
#define jit_bmcr_l(label, s1, s2) (TESTQrr((s1), (s2)), JZm(label), _jit.x.pc)
#define jit_boaddr_l(label, s1, s2) (ADDQrr((s2), (s1)), JOm(label), _jit.x.pc)
#define jit_bosubr_l(label, s1, s2) (SUBQrr((s2), (s1)), JOm(label), _jit.x.pc)
#define jit_boaddr_ul(label, s1, s2) (ADDQrr((s2), (s1)), JCm(label), _jit.x.pc)
#define jit_bosubr_ul(label, s1, s2) (SUBQrr((s2), (s1)), JCm(label), _jit.x.pc)
#define jit_boaddi_l(label, rs, is) (ADDQir((is), (rs)), JOm(label), _jit.x.pc)
#define jit_bosubi_l(label, rs, is) (SUBQir((is), (rs)), JOm(label), _jit.x.pc)
#define jit_boaddi_ul(label, rs, is) (ADDQir((is), (rs)), JCm(label), _jit.x.pc)
#define jit_bosubi_ul(label, rs, is) (SUBQir((is), (rs)), JCm(label), _jit.x.pc)
#define jit_patch_long_at(jump_pc,v) (*_PSL((jump_pc) - sizeof(long)) = _jit_SL((jit_insn *)(v)))
#define jit_patch_short_at(jump_pc,v) (*_PSI((jump_pc) - sizeof(int)) = _jit_SI((jit_insn *)(v) - (jump_pc)))
#define jit_patch_at(jump_pc,v) (_jitl.long_jumps ? jit_patch_long_at((jump_pc)-3, v) : jit_patch_short_at(jump_pc, v))
#define jit_patch_calli(pa,pv) (*_PSL((pa) - sizeof(long)) = _jit_SL((pv)))
#define jit_ret() (LEAVE_(), POPQr(_R14), POPQr(_R13), POPQr(_R12), POPQr(_EBX), RET_())
#define jit_bare_ret() RET_()
/* Memory */
/* Used to implement ldc, stc, ... We have SIL and friends which simplify it all. */
#define jit_movbrm(rs, dd, db, di, ds) MOVBrm(jit_reg8(rs), dd, db, di, ds)
#define jit_ldr_c(d, rs) MOVSBQmr(0, (rs), 0, 0, (d))
#define jit_ldxr_c(d, s1, s2) MOVSBQmr(0, (s1), (s2), 1, (d))
#define jit_ldr_s(d, rs) MOVSWQmr(0, (rs), 0, 0, (d))
#define jit_ldxr_s(d, s1, s2) MOVSWQmr(0, (s1), (s2), 1, (d))
#define jit_ldi_c(d, is) (_u32P((long)(is)) ? MOVSBQmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_c(d, JIT_REXTMP)))
#define jit_ldxi_c(d, rs, is) (_u32P((long)(is)) ? MOVSBQmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_c(d, rs, JIT_REXTMP)))
#define jit_ldi_uc(d, is) (_u32P((long)(is)) ? MOVZBLmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_uc(d, JIT_REXTMP)))
#define jit_ldxi_uc(d, rs, is) (_u32P((long)(is)) ? MOVZBLmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_uc(d, rs, JIT_REXTMP)))
#define jit_sti_c(id, rs) (_u32P((long)(id)) ? MOVBrm(jit_reg8(rs), (id), 0, 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_str_c(JIT_REXTMP, rs)))
#define jit_stxi_c(id, rd, rs) (_u32P((long)(id)) ? MOVBrm(jit_reg8(rs), (id), (rd), 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_stxr_c(JIT_REXTMP, rd, rs)))
#define jit_ldi_s(d, is) (_u32P((long)(is)) ? MOVSWQmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_s(d, JIT_REXTMP)))
#define jit_ldxi_s(d, rs, is) (_u32P((long)(is)) ? MOVSWQmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_s(d, rs, JIT_REXTMP)))
#define jit_ldi_us(d, is) (_u32P((long)(is)) ? MOVZWLmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_us(d, JIT_REXTMP)))
#define jit_ldxi_us(d, rs, is) (_u32P((long)(is)) ? MOVZWLmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_us(d, rs, JIT_REXTMP)))
#define jit_sti_s(id, rs) (_u32P((long)(id)) ? MOVWrm(jit_reg16(rs), (id), 0, 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_str_s(JIT_REXTMP, rs)))
#define jit_stxi_s(id, rd, rs) (_u32P((long)(id)) ? MOVWrm(jit_reg16(rs), (id), (rd), 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_stxr_s(JIT_REXTMP, rd, rs)))
#define jit_ldi_ui(d, is) (_u32P((long)(is)) ? MOVLmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_ui(d, JIT_REXTMP)))
#define jit_ldxi_ui(d, rs, is) (_u32P((long)(is)) ? MOVLmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_ui(d, rs, JIT_REXTMP)))
#define jit_ldi_i(d, is) (_u32P((long)(is)) ? MOVSLQmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_i(d, JIT_REXTMP)))
#define jit_ldxi_i(d, rs, is) (_u32P((long)(is)) ? MOVSLQmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_i(d, rs, JIT_REXTMP)))
#define jit_sti_i(id, rs) (_u32P((long)(id)) ? MOVLrm((rs), (id), 0, 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_str_i(JIT_REXTMP, rs)))
#define jit_stxi_i(id, rd, rs) (_u32P((long)(id)) ? MOVLrm((rs), (id), (rd), 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_stxr_i(JIT_REXTMP, rd, rs)))
#define jit_ldi_l(d, is) (_u32P((long)(is)) ? MOVQmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_l(d, JIT_REXTMP)))
#define jit_ldxi_l(d, rs, is) (_u32P((long)(is)) ? MOVQmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_l(d, rs, JIT_REXTMP)))
#define jit_sti_l(id, rs) (_u32P((long)(id)) ? MOVQrm((rs), (id), 0, 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_str_l(JIT_REXTMP, rs)))
#define jit_stxi_l(id, rd, rs) (_u32P((long)(id)) ? MOVQrm((rs), (id), (rd), 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_stxr_l(JIT_REXTMP, rd, rs)))
#define jit_ldr_ui(d, rs) MOVLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_ui(d, s1, s2) MOVLmr(0, (s1), (s2), 1, (d))
#define jit_ldr_i(d, rs) MOVSLQmr(0, (rs), 0, 0, (d))
#define jit_ldxr_i(d, s1, s2) MOVSLQmr(0, (s1), (s2), 1, (d))
#define jit_ldr_l(d, rs) MOVQmr(0, (rs), 0, 0, (d))
#define jit_ldxr_l(d, s1, s2) MOVQmr(0, (s1), (s2), 1, (d))
#define jit_str_l(rd, rs) MOVQrm((rs), 0, (rd), 0, 0)
#define jit_stxr_l(d1, d2, rs) MOVQrm((rs), 0, (d1), (d2), 1)
#define jit_blti_l(label, rs, is) jit_bra_l0((rs), (is), JLm(label), JSm(label) )
#define jit_blei_l(label, rs, is) jit_bra_l ((rs), (is), JLEm(label) )
#define jit_bgti_l(label, rs, is) jit_bra_l ((rs), (is), JGm(label) )
#define jit_bgei_l(label, rs, is) jit_bra_l0((rs), (is), JGEm(label), JNSm(label) )
#define jit_beqi_l(label, rs, is) jit_bra_l0((rs), (is), JEm(label), JEm(label) )
#define jit_bnei_l(label, rs, is) jit_bra_l0((rs), (is), JNEm(label), JNEm(label) )
#define jit_blti_ul(label, rs, is) jit_bra_l ((rs), (is), JBm(label) )
#define jit_blei_ul(label, rs, is) jit_bra_l0((rs), (is), JBEm(label), JEm(label) )
#define jit_bgti_ul(label, rs, is) jit_bra_l0((rs), (is), JAm(label), JNEm(label) )
#define jit_bgei_ul(label, rs, is) jit_bra_l ((rs), (is), JAEm(label) )
#define jit_bmsi_l(label, rs, is) (jit_reduceQ(TEST, (is), (rs)), JNZm(label), _jit.x.pc)
#define jit_bmci_l(label, rs, is) (jit_reduceQ(TEST, (is), (rs)), JZm(label), _jit.x.pc)
#define jit_pushr_l(rs) jit_pushr_i(rs)
#define jit_popr_l(rs) jit_popr_i(rs)
#define jit_pusharg_l(rs) jit_pusharg_i(rs)
#define jit_retval_l(rd) ((void)jit_movr_l ((rd), _EAX))
#define jit_bltr_l(label, s1, s2) jit_bra_qr((s1), (s2), JLm(label) )
#define jit_bler_l(label, s1, s2) jit_bra_qr((s1), (s2), JLEm(label) )
#define jit_bgtr_l(label, s1, s2) jit_bra_qr((s1), (s2), JGm(label) )
#define jit_bger_l(label, s1, s2) jit_bra_qr((s1), (s2), JGEm(label) )
#define jit_beqr_l(label, s1, s2) jit_bra_qr((s1), (s2), JEm(label) )
#define jit_bner_l(label, s1, s2) jit_bra_qr((s1), (s2), JNEm(label) )
#define jit_bltr_ul(label, s1, s2) jit_bra_qr((s1), (s2), JBm(label) )
#define jit_bler_ul(label, s1, s2) jit_bra_qr((s1), (s2), JBEm(label) )
#define jit_bgtr_ul(label, s1, s2) jit_bra_qr((s1), (s2), JAm(label) )
#define jit_bger_ul(label, s1, s2) jit_bra_qr((s1), (s2), JAEm(label) )
/* Bool operations. */
#define jit_bool_qr(d, s1, s2, op) \
(jit_replace8(d, CMPQrr(s2, s1), op))
#define jit_bool_qi(d, rs, is, op) \
(jit_replace8(d, CMPQir(is, rs), op))
/* When CMP with 0 can be replaced with TEST */
#define jit_bool_qi0(d, rs, is, op, op0) \
((is) != 0 \
? (jit_replace8(d, CMPQir(is, rs), op)) \
: (jit_replace8(d, TESTQrr(rs, rs), op0)))
#define jit_ltr_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETLr )
#define jit_ler_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETLEr )
#define jit_gtr_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETGr )
#define jit_ger_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETGEr )
#define jit_eqr_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETEr )
#define jit_ner_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETNEr )
#define jit_ltr_ul(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETBr )
#define jit_ler_ul(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETBEr )
#define jit_gtr_ul(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETAr )
#define jit_ger_ul(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETAEr )
#define jit_lti_l(d, rs, is) jit_bool_qi0((d), (rs), (is), SETLr, SETSr )
#define jit_lei_l(d, rs, is) jit_bool_qi ((d), (rs), (is), SETLEr )
#define jit_gti_l(d, rs, is) jit_bool_qi ((d), (rs), (is), SETGr )
#define jit_gei_l(d, rs, is) jit_bool_qi0((d), (rs), (is), SETGEr, SETNSr )
#define jit_eqi_l(d, rs, is) jit_bool_qi0((d), (rs), (is), SETEr, SETEr )
#define jit_nei_l(d, rs, is) jit_bool_qi0((d), (rs), (is), SETNEr, SETNEr )
#define jit_lti_ul(d, rs, is) jit_bool_qi ((d), (rs), (is), SETBr )
#define jit_lei_ul(d, rs, is) jit_bool_qi0((d), (rs), (is), SETBEr, SETEr )
#define jit_gti_ul(d, rs, is) jit_bool_qi0((d), (rs), (is), SETAr, SETNEr )
#define jit_gei_ul(d, rs, is) jit_bool_qi0((d), (rs), (is), SETAEr, INCLr )
/* Multiplication/division. */
#define jit_mulr_ul_(s1, s2) \
jit_qopr_(_RAX, s1, s2, MULQr(s1), MULQr(s2))
#define jit_mulr_l_(s1, s2) \
jit_qopr_(_RAX, s1, s2, IMULQr(s1), IMULQr(s2))
#define jit_muli_l_(is, rs) \
(MOVQir(is, rs == _RAX ? _RDX : _RAX), \
IMULQr(rs == _RAX ? _RDX : rs))
#define jit_muli_ul_(is, rs) \
(MOVQir(is, rs == _RAX ? _RDX : _RAX), \
IMULQr(rs == _RAX ? _RDX : rs))
#define jit_divi_l_(result, d, rs, is) \
(jit_might (d, _RAX, jit_pushr_l(_RAX)), \
jit_might (d, _RCX, jit_pushr_l(_RCX)), \
jit_might (d, _RDX, jit_pushr_l(_RDX)), \
jit_might (rs, _RAX, MOVQrr(rs, _RAX)), \
jit_might (rs, _RDX, MOVQrr(rs, _RDX)), \
MOVQir(is, _RCX), \
SARQir(63, _RDX), \
IDIVQr(_RCX), \
jit_might(d, result, MOVQrr(result, d)), \
jit_might(d, _RDX, jit_popr_l(_RDX)), \
jit_might(d, _RCX, jit_popr_l(_RCX)), \
jit_might(d, _RAX, jit_popr_l(_RAX)))
#define jit_divr_l_(result, d, s1, s2) \
(jit_might (d, _RAX, jit_pushr_l(_RAX)), \
jit_might (d, _RCX, jit_pushr_l(_RCX)), \
jit_might (d, _RDX, jit_pushr_l(_RDX)), \
((s1 == _RCX) ? jit_pushr_l(_RCX) : 0), \
jit_might (s2, _RCX, MOVQrr(s2, _RCX)), \
((s1 == _RCX) ? jit_popr_l(_RDX) : \
jit_might (s1, _RDX, MOVQrr(s1, _RDX))), \
MOVQrr(_RDX, _RAX), \
SARQir(63, _RDX), \
IDIVQr(_RCX), \
jit_might(d, result, MOVQrr(result, d)), \
jit_might(d, _RDX, jit_popr_l(_RDX)), \
jit_might(d, _RCX, jit_popr_l(_RCX)), \
jit_might(d, _RAX, jit_popr_l(_RAX)))
#define jit_divi_ul_(result, d, rs, is) \
(jit_might (d, _RAX, jit_pushr_l(_RAX)), \
jit_might (d, _RCX, jit_pushr_l(_RCX)), \
jit_might (d, _RDX, jit_pushr_l(_RDX)), \
jit_might (rs, _RAX, MOVQrr(rs, _RAX)), \
MOVQir(is, _RCX), \
XORQrr(_RDX, _RDX), \
DIVQr(_RCX), \
jit_might(d, result, MOVQrr(result, d)), \
jit_might(d, _RDX, jit_popr_l(_RDX)), \
jit_might(d, _RCX, jit_popr_l(_RCX)), \
jit_might(d, _RAX, jit_popr_l(_RAX)))
#define jit_divr_ul_(result, d, s1, s2) \
(jit_might (d, _RAX, jit_pushr_l(_RAX)), \
jit_might (d, _RCX, jit_pushr_l(_RCX)), \
jit_might (d, _RDX, jit_pushr_l(_RDX)), \
((s1 == _RCX) ? jit_pushr_l(_RCX) : 0), \
jit_might (s2, _RCX, MOVQrr(s2, _RCX)), \
((s1 == _RCX) ? jit_popr_l(_RAX) : \
jit_might (s1, _RAX, MOVQrr(s1, _RAX))), \
XORQrr(_RDX, _RDX), \
DIVQr(_RCX), \
jit_might(d, result, MOVQrr(result, d)), \
jit_might(d, _RDX, jit_popr_l(_RDX)), \
jit_might(d, _RCX, jit_popr_l(_RCX)), \
jit_might(d, _RAX, jit_popr_l(_RAX)))
#define jit_muli_l(d, rs, is) jit_qop_ ((d), (rs), (is), IMULQir((is), (d)), IMULQrr(JIT_REXTMP, (d)) )
#define jit_mulr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), IMULQrr((s1), (d)), IMULQrr((s2), (d)) )
/* As far as low bits are concerned, signed and unsigned multiplies are
exactly the same. */
#define jit_muli_ul(d, rs, is) jit_qop_ ((d), (rs), (is), IMULQir((is), (d)), IMULQrr(JIT_REXTMP, (d)) )
#define jit_mulr_ul(d, s1, s2) jit_qopr_((d), (s1), (s2), IMULQrr((s1), (d)), IMULQrr((s2), (d)) )
#define jit_hmuli_l(d, rs, is) \
((d) == _RDX ? ( jit_pushr_l(_RAX), jit_muli_l_((is), (rs)), jit_popr_l(_RAX) ) : \
((d) == _RAX ? (jit_pushr_l(_RDX), jit_muli_l_((is), (rs)), MOVQrr(_RDX, _RAX), jit_popr_l(_RDX) ) : \
(jit_pushr_l(_RDX), jit_pushr_l(_RAX), jit_muli_l_((is), (rs)), MOVQrr(_RDX, (d)), jit_popr_l(_RAX), jit_popr_l(_RDX) )))
#define jit_hmulr_l(d, s1, s2) \
((d) == _RDX ? ( jit_pushr_l(_RAX), jit_mulr_l_((s1), (s2)), jit_popr_l(_RAX) ) : \
((d) == _RAX ? (jit_pushr_l(_RDX), jit_mulr_l_((s1), (s2)), MOVQrr(_RDX, _RAX), jit_popr_l(_RDX) ) : \
(jit_pushr_l(_RDX), jit_pushr_l(_RAX), jit_mulr_l_((s1), (s2)), MOVQrr(_RDX, (d)), jit_popr_l(_RAX), jit_popr_l(_RDX) )))
#define jit_hmuli_ul(d, rs, is) \
((d) == _RDX ? ( jit_pushr_l(_RAX), jit_muli_ul_((is), (rs)), jit_popr_l(_RAX) ) : \
((d) == _RAX ? (jit_pushr_l(_RDX), jit_muli_ul_((is), (rs)), MOVQrr(_RDX, _RAX), jit_popr_l(_RDX) ) : \
(jit_pushr_l(_RDX), jit_pushr_l(_RAX), jit_muli_ul_((is), (rs)), MOVQrr(_RDX, (d)), jit_popr_l(_RAX), jit_popr_l(_RDX) )))
#define jit_hmulr_ul(d, s1, s2) \
((d) == _RDX ? ( jit_pushr_l(_RAX), jit_mulr_ul_((s1), (s2)), jit_popr_l(_RAX) ) : \
((d) == _RAX ? (jit_pushr_l(_RDX), jit_mulr_ul_((s1), (s2)), MOVQrr(_RDX, _RAX), jit_popr_l(_RDX) ) : \
(jit_pushr_l(_RDX), jit_pushr_l(_RAX), jit_mulr_ul_((s1), (s2)), MOVQrr(_RDX, (d)), jit_popr_l(_RAX), jit_popr_l(_RDX) )))
#define jit_divi_l(d, rs, is) jit_divi_l_(_RAX, (d), (rs), (is))
#define jit_divi_ul(d, rs, is) jit_divi_ul_(_RAX, (d), (rs), (is))
#define jit_modi_l(d, rs, is) jit_divi_l_(_RDX, (d), (rs), (is))
#define jit_modi_ul(d, rs, is) jit_divi_ul_(_RDX, (d), (rs), (is))
#define jit_divr_l(d, s1, s2) jit_divr_l_(_RAX, (d), (s1), (s2))
#define jit_divr_ul(d, s1, s2) jit_divr_ul_(_RAX, (d), (s1), (s2))
#define jit_modr_l(d, s1, s2) jit_divr_l_(_RDX, (d), (s1), (s2))
#define jit_modr_ul(d, s1, s2) jit_divr_ul_(_RDX, (d), (s1), (s2))
#endif /* __lightning_core_h */

View File

@@ -1,366 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer (i386 version)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
* Written by Paolo Bonzini and Matthew Flatt.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_core_i386_h
#define __lightning_core_i386_h
#define JIT_FP _EBP
#define JIT_SP _ESP
#define JIT_RET _EAX
/* 3-parameter operation */
#define jit_opr_(d, s1, s2, op1d, op2d) \
( (s2 == d) ? op1d : \
( ((s1 == d) ? (void)0 : (void)MOVLrr(s1, d)), op2d ) \
)
/* 3-parameter operation, with immediate */
#define jit_op_(d, s1, op2d) \
((s1 == d) ? op2d : (MOVLrr(s1, d), op2d))
/* 3-parameter operation, optimizable */
#define jit_opo_(d, s1, s2, op1d, op2d, op12d) \
((s2 == d) ? op2d : \
((s1 == d) ? op1d : op12d))
/* 3-parameter operation, optimizable, with immediate */
#define jit_opi_(d, rs, opdi, opdri) \
((rs == d) ? opdi : opdri)
/* For LT, LE, ... */
#define jit_replace8(d, cmp, op) \
(jit_check8(d) \
? ((cmp), \
MOVLir(0, (d)), \
op(_rR(d) | _AL)) \
: (jit_pushr_i(_EAX), (cmp), \
MOVLir(0, _EAX), \
op(_AL), MOVLrr(_EAX, (d)), jit_popr_i(_EAX)))
#define jit_bool_r(d, s1, s2, op) \
(jit_replace8(d, CMPLrr(s2, s1), op))
#define jit_bool_i(d, rs, is, op) \
(jit_replace8(d, CMPLir(is, rs), op))
/* When CMP with 0 can be replaced with TEST */
#define jit_bool_i0(d, rs, is, op, op0) \
((is) != 0 \
? (jit_replace8(d, CMPLir(is, rs), op)) \
: (jit_replace8(d, TESTLrr(rs, rs), op0)))
/* For BLT, BLE, ... */
#define jit_bra_r(s1, s2, op) (CMPLrr(s2, s1), op, _jit.x.pc)
#define jit_bra_i(rs, is, op) (CMPLir(is, rs), op, _jit.x.pc)
/* When CMP with 0 can be replaced with TEST */
#define jit_bra_i0(rs, is, op, op0) \
( (is) == 0 ? (TESTLrr(rs, rs), op0, _jit.x.pc) : (CMPLir(is, rs), op, _jit.x.pc))
/* Reduce arguments of XOR/OR/TEST */
#define jit_reduce_(op) op
#define jit_reduce(op, is, rs) \
(_u8P(is) && jit_check8(rs) ? jit_reduce_(op##Bir(is, jit_reg8(rs))) : \
(_u16P(is) && JIT_CAN_16 ? jit_reduce_(op##Wir(is, jit_reg16(rs))) : \
jit_reduce_(op##Lir(is, rs)) ))
/* Helper macros for MUL/DIV/IDIV */
#define jit_might(d, s1, op) \
((s1 == d) ? 0 : op)
#define jit_mulr_ui_(s1, s2) jit_opr_(_EAX, s1, s2, MULLr(s1), MULLr(s2))
#define jit_mulr_i_(s1, s2) jit_opr_(_EAX, s1, s2, IMULLr(s1), IMULLr(s2))
#define jit_muli_i_(is, rs) \
(MOVLir(is, rs == _EAX ? _EDX : _EAX), \
IMULLr(rs == _EAX ? _EDX : rs))
#define jit_muli_ui_(is, rs) \
(MOVLir(is, rs == _EAX ? _EDX : _EAX), \
IMULLr(rs == _EAX ? _EDX : rs))
#define jit_divi_i_(result, d, rs, is) \
(jit_might (d, _EAX, jit_pushr_i(_EAX)), \
jit_might (d, _ECX, jit_pushr_i(_ECX)), \
jit_might (d, _EDX, jit_pushr_i(_EDX)), \
jit_might (rs, _EAX, MOVLrr(rs, _EAX)), \
jit_might (rs, _EDX, MOVLrr(rs, _EDX)), \
MOVLir(is, _ECX), \
SARLir(31, _EDX), \
IDIVLr(_ECX), \
jit_might(d, result, MOVLrr(result, d)), \
jit_might(d, _EDX, jit_popr_i(_EDX)), \
jit_might(d, _ECX, jit_popr_i(_ECX)), \
jit_might(d, _EAX, jit_popr_i(_EAX)))
#define jit_divr_i_(result, d, s1, s2) \
(jit_might (d, _EAX, jit_pushr_i(_EAX)), \
jit_might (d, _ECX, jit_pushr_i(_ECX)), \
jit_might (d, _EDX, jit_pushr_i(_EDX)), \
((s1 == _ECX) ? jit_pushr_i(_ECX) : 0), \
jit_might (s2, _ECX, MOVLrr(s2, _ECX)), \
((s1 == _ECX) ? jit_popr_i(_EDX) : \
jit_might (s1, _EDX, MOVLrr(s1, _EDX))), \
MOVLrr(_EDX, _EAX), \
SARLir(31, _EDX), \
IDIVLr(_ECX), \
jit_might(d, result, MOVLrr(result, d)), \
jit_might(d, _EDX, jit_popr_i(_EDX)), \
jit_might(d, _ECX, jit_popr_i(_ECX)), \
jit_might(d, _EAX, jit_popr_i(_EAX)))
#define jit_divi_ui_(result, d, rs, is) \
(jit_might (d, _EAX, jit_pushr_i(_EAX)), \
jit_might (d, _ECX, jit_pushr_i(_ECX)), \
jit_might (d, _EDX, jit_pushr_i(_EDX)), \
jit_might (rs, _EAX, MOVLrr(rs, _EAX)), \
MOVLir(is, _ECX), \
XORLrr(_EDX, _EDX), \
DIVLr(_ECX), \
jit_might(d, result, MOVLrr(result, d)), \
jit_might(d, _EDX, jit_popr_i(_EDX)), \
jit_might(d, _ECX, jit_popr_i(_ECX)), \
jit_might(d, _EAX, jit_popr_i(_EAX)))
#define jit_divr_ui_(result, d, s1, s2) \
(jit_might (d, _EAX, jit_pushr_i(_EAX)), \
jit_might (d, _ECX, jit_pushr_i(_ECX)), \
jit_might (d, _EDX, jit_pushr_i(_EDX)), \
((s1 == _ECX) ? jit_pushr_i(_ECX) : 0), \
jit_might (s2, _ECX, MOVLrr(s2, _ECX)), \
((s1 == _ECX) ? jit_popr_i(_EAX) : \
jit_might (s1, _EAX, MOVLrr(s1, _EAX))), \
XORLrr(_EDX, _EDX), \
DIVLr(_ECX), \
jit_might(d, result, MOVLrr(result, d)), \
jit_might(d, _EDX, jit_popr_i(_EDX)), \
jit_might(d, _ECX, jit_popr_i(_ECX)), \
jit_might(d, _EAX, jit_popr_i(_EAX)))
/* ALU */
#define jit_addi_i(d, rs, is) jit_opi_((d), (rs), ADDLir((is), (d)), LEALmr((is), (rs), 0, 0, (d)) )
#define jit_addr_i(d, s1, s2) jit_opo_((d), (s1), (s2), ADDLrr((s2), (d)), ADDLrr((s1), (d)), LEALmr(0, (s1), (s2), 1, (d)) )
#define jit_addci_i(d, rs, is) jit_op_ ((d), (rs), ADDLir((is), (d)) )
#define jit_addcr_i(d, s1, s2) jit_opr_((d), (s1), (s2), ADDLrr((s1), (d)), ADDLrr((s2), (d)) )
#define jit_addxi_i(d, rs, is) jit_op_ ((d), (rs), ADCLir((is), (d)) )
#define jit_addxr_i(d, s1, s2) jit_opr_((d), (s1), (s2), ADCLrr((s1), (d)), ADCLrr((s2), (d)) )
#define jit_andi_i(d, rs, is) jit_op_ ((d), (rs), ANDLir((is), (d)) )
#define jit_andr_i(d, s1, s2) jit_opr_((d), (s1), (s2), ANDLrr((s1), (d)), ANDLrr((s2), (d)) )
#define jit_orr_i(d, s1, s2) jit_opr_((d), (s1), (s2), ORLrr((s1), (d)), ORLrr((s2), (d)) )
#define jit_subr_i(d, s1, s2) jit_opr_((d), (s1), (s2), (SUBLrr((s1), (d)), NEGLr(d)), SUBLrr((s2), (d)) )
#define jit_subcr_i(d, s1, s2) jit_subr_i((d), (s1), (s2))
#define jit_subxr_i(d, s1, s2) jit_opr_((d), (s1), (s2), SBBLrr((s1), (d)), SBBLrr((s2), (d)) )
#define jit_subxi_i(d, rs, is) jit_op_ ((d), (rs), SBBLir((is), (d)) )
#define jit_xorr_i(d, s1, s2) jit_opr_((d), (s1), (s2), XORLrr((s1), (d)), XORLrr((s2), (d)) )
/* These can sometimes use byte or word versions! */
#define jit_ori_i(d, rs, is) jit_op_ ((d), (rs), jit_reduce(OR, (is), (d)) )
#define jit_xori_i(d, rs, is) jit_op_ ((d), (rs), jit_reduce(XOR, (is), (d)) )
#define jit_muli_i(d, rs, is) jit_op_ ((d), (rs), IMULLir((is), (d)) )
#define jit_mulr_i(d, s1, s2) jit_opr_((d), (s1), (s2), IMULLrr((s1), (d)), IMULLrr((s2), (d)) )
/* As far as low bits are concerned, signed and unsigned multiplies are
exactly the same. */
#define jit_muli_ui(d, rs, is) jit_op_ ((d), (rs), IMULLir((is), (d)) )
#define jit_mulr_ui(d, s1, s2) jit_opr_((d), (s1), (s2), IMULLrr((s1), (d)), IMULLrr((s2), (d)) )
#define jit_hmuli_i(d, rs, is) \
((d) == _EDX ? ( jit_pushr_i(_EAX), jit_muli_i_((is), (rs)), jit_popr_i(_EAX) ) : \
((d) == _EAX ? (jit_pushr_i(_EDX), jit_muli_i_((is), (rs)), MOVLrr(_EDX, _EAX), jit_popr_i(_EDX) ) : \
(jit_pushr_i(_EDX), jit_pushr_i(_EAX), jit_muli_i_((is), (rs)), MOVLrr(_EDX, (d)), jit_popr_i(_EAX), jit_popr_i(_EDX) )))
#define jit_hmulr_i(d, s1, s2) \
((d) == _EDX ? ( jit_pushr_i(_EAX), jit_mulr_i_((s1), (s2)), jit_popr_i(_EAX) ) : \
((d) == _EAX ? (jit_pushr_i(_EDX), jit_mulr_i_((s1), (s2)), MOVLrr(_EDX, _EAX), jit_popr_i(_EDX) ) : \
(jit_pushr_i(_EDX), jit_pushr_i(_EAX), jit_mulr_i_((s1), (s2)), MOVLrr(_EDX, (d)), jit_popr_i(_EAX), jit_popr_i(_EDX) )))
#define jit_hmuli_ui(d, rs, is) \
((d) == _EDX ? ( jit_pushr_i(_EAX), jit_muli_ui_((is), (rs)), jit_popr_i(_EAX) ) : \
((d) == _EAX ? (jit_pushr_i(_EDX), jit_muli_ui_((is), (rs)), MOVLrr(_EDX, _EAX), jit_popr_i(_EDX) ) : \
(jit_pushr_i(_EDX), jit_pushr_i(_EAX), jit_muli_ui_((is), (rs)), MOVLrr(_EDX, (d)), jit_popr_i(_EAX), jit_popr_i(_EDX) )))
#define jit_hmulr_ui(d, s1, s2) \
((d) == _EDX ? ( jit_pushr_i(_EAX), jit_mulr_ui_((s1), (s2)), jit_popr_i(_EAX) ) : \
((d) == _EAX ? (jit_pushr_i(_EDX), jit_mulr_ui_((s1), (s2)), MOVLrr(_EDX, _EAX), jit_popr_i(_EDX) ) : \
(jit_pushr_i(_EDX), jit_pushr_i(_EAX), jit_mulr_ui_((s1), (s2)), MOVLrr(_EDX, (d)), jit_popr_i(_EAX), jit_popr_i(_EDX) )))
#define jit_divi_i(d, rs, is) jit_divi_i_(_EAX, (d), (rs), (is))
#define jit_divi_ui(d, rs, is) jit_divi_ui_(_EAX, (d), (rs), (is))
#define jit_modi_i(d, rs, is) jit_divi_i_(_EDX, (d), (rs), (is))
#define jit_modi_ui(d, rs, is) jit_divi_ui_(_EDX, (d), (rs), (is))
#define jit_divr_i(d, s1, s2) jit_divr_i_(_EAX, (d), (s1), (s2))
#define jit_divr_ui(d, s1, s2) jit_divr_ui_(_EAX, (d), (s1), (s2))
#define jit_modr_i(d, s1, s2) jit_divr_i_(_EDX, (d), (s1), (s2))
#define jit_modr_ui(d, s1, s2) jit_divr_ui_(_EDX, (d), (s1), (s2))
/* Shifts */
#define jit_shift(d, s1, s2, m) \
((d) == _ECX || (d) == (s2) \
? ((s2) == _EAX \
? jit_fixd(d, _EDX, jit_shift2(_EDX, s1, s2, m)) \
: jit_fixd(d, _EAX, jit_shift2(_EAX, s1, s2, m))) \
: jit_shift2(d, s1, s2, m))
/* Shift operation, assuming d != s2 or ECX */
#define jit_shift2(d, s1, s2, m) \
jit_op_(d, s1, jit_cfixs(s2, _ECX, m(_CL, d)))
/* Substitute x for destination register d */
#define jit_fixd(d, x, op) \
(jit_pushr_i(x), op, jit_movr_i(d, x), jit_popr_i(x))
/* Conditionally substitute y for source register s */
#define jit_cfixs(s, y, op) \
((s) == (y) ? op : \
(jit_pushr_i(y), jit_movr_i(y, s), op, jit_popr_i(y)))
#define jit_lshi_i(d, rs, is) ((is) <= 3 ? LEALmr(0, 0, (rs), 1 << (is), (d)) : jit_op_ ((d), (rs), SHLLir((is), (d)) ))
#define jit_rshi_i(d, rs, is) jit_op_ ((d), (rs), SARLir((is), (d)) )
#define jit_rshi_ui(d, rs, is) jit_op_ ((d), (rs), SHRLir((is), (d)) )
#define jit_lshr_i(d, r1, r2) jit_shift((d), (r1), (r2), SHLLrr)
#define jit_rshr_i(d, r1, r2) jit_shift((d), (r1), (r2), SARLrr)
#define jit_rshr_ui(d, r1, r2) jit_shift((d), (r1), (r2), SHRLrr)
/* Stack */
#define jit_retval_i(rd) ((void)jit_movr_i ((rd), _EAX))
/* Unary */
#define jit_negr_i(d, rs) jit_opi_((d), (rs), NEGLr(d), (XORLrr((d), (d)), SUBLrr((rs), (d))) )
#define jit_movr_i(d, rs) ((void)((rs) == (d) ? 0 : MOVLrr((rs), (d))))
#define jit_movi_i(d, is) ((is) ? MOVLir((is), (d)) : XORLrr ((d), (d)) )
#define jit_patch_movi(pa,pv) (*_PSL((pa) - sizeof(long)) = _jit_SL((pv)))
#define jit_ntoh_ui(d, rs) jit_op_((d), (rs), BSWAPLr(d))
#define jit_ntoh_us(d, rs) jit_op_((d), (rs), RORWir(8, d))
/* Boolean */
#define jit_ltr_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETLr )
#define jit_ler_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETLEr )
#define jit_gtr_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETGr )
#define jit_ger_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETGEr )
#define jit_eqr_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETEr )
#define jit_ner_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETNEr )
#define jit_ltr_ui(d, s1, s2) jit_bool_r((d), (s1), (s2), SETBr )
#define jit_ler_ui(d, s1, s2) jit_bool_r((d), (s1), (s2), SETBEr )
#define jit_gtr_ui(d, s1, s2) jit_bool_r((d), (s1), (s2), SETAr )
#define jit_ger_ui(d, s1, s2) jit_bool_r((d), (s1), (s2), SETAEr )
#define jit_lti_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETLr, SETSr )
#define jit_lei_i(d, rs, is) jit_bool_i ((d), (rs), (is), SETLEr )
#define jit_gti_i(d, rs, is) jit_bool_i ((d), (rs), (is), SETGr )
#define jit_gei_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETGEr, SETNSr )
#define jit_eqi_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETEr, SETEr )
#define jit_nei_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETNEr, SETNEr )
#define jit_lti_ui(d, rs, is) jit_bool_i ((d), (rs), (is), SETBr )
#define jit_lei_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETBEr, SETEr )
#define jit_gti_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETAr, SETNEr )
#define jit_gei_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETAEr, INCLr )
/* Jump */
#define jit_bltr_i(label, s1, s2) jit_bra_r((s1), (s2), JLm(label) )
#define jit_bler_i(label, s1, s2) jit_bra_r((s1), (s2), JLEm(label) )
#define jit_bgtr_i(label, s1, s2) jit_bra_r((s1), (s2), JGm(label) )
#define jit_bger_i(label, s1, s2) jit_bra_r((s1), (s2), JGEm(label) )
#define jit_beqr_i(label, s1, s2) jit_bra_r((s1), (s2), JEm(label) )
#define jit_bner_i(label, s1, s2) jit_bra_r((s1), (s2), JNEm(label) )
#define jit_bltr_ui(label, s1, s2) jit_bra_r((s1), (s2), JBm(label) )
#define jit_bler_ui(label, s1, s2) jit_bra_r((s1), (s2), JBEm(label) )
#define jit_bgtr_ui(label, s1, s2) jit_bra_r((s1), (s2), JAm(label) )
#define jit_bger_ui(label, s1, s2) jit_bra_r((s1), (s2), JAEm(label) )
#define jit_bmsr_i(label, s1, s2) (TESTLrr((s1), (s2)), JNZm(label), _jit.x.pc)
#define jit_bmcr_i(label, s1, s2) (TESTLrr((s1), (s2)), JZm(label), _jit.x.pc)
#define jit_boaddr_i(label, s1, s2) (ADDLrr((s2), (s1)), JOm(label), _jit.x.pc)
#define jit_bosubr_i(label, s1, s2) (SUBLrr((s2), (s1)), JOm(label), _jit.x.pc)
#define jit_boaddr_ui(label, s1, s2) (ADDLrr((s2), (s1)), JCm(label), _jit.x.pc)
#define jit_bosubr_ui(label, s1, s2) (SUBLrr((s2), (s1)), JCm(label), _jit.x.pc)
#define jit_blti_i(label, rs, is) jit_bra_i0((rs), (is), JLm(label), JSm(label) )
#define jit_blei_i(label, rs, is) jit_bra_i ((rs), (is), JLEm(label) )
#define jit_bgti_i(label, rs, is) jit_bra_i ((rs), (is), JGm(label) )
#define jit_bgei_i(label, rs, is) jit_bra_i0((rs), (is), JGEm(label), JNSm(label) )
#define jit_beqi_i(label, rs, is) jit_bra_i0((rs), (is), JEm(label), JEm(label) )
#define jit_bnei_i(label, rs, is) jit_bra_i0((rs), (is), JNEm(label), JNEm(label) )
#define jit_blti_ui(label, rs, is) jit_bra_i ((rs), (is), JBm(label) )
#define jit_blei_ui(label, rs, is) jit_bra_i0((rs), (is), JBEm(label), JEm(label) )
#define jit_bgti_ui(label, rs, is) jit_bra_i0((rs), (is), JAm(label), JNEm(label) )
#define jit_bgei_ui(label, rs, is) jit_bra_i ((rs), (is), JAEm(label) )
#define jit_boaddi_i(label, rs, is) (ADDLir((is), (rs)), JOm(label), _jit.x.pc)
#define jit_bosubi_i(label, rs, is) (SUBLir((is), (rs)), JOm(label), _jit.x.pc)
#define jit_boaddi_ui(label, rs, is) (ADDLir((is), (rs)), JCm(label), _jit.x.pc)
#define jit_bosubi_ui(label, rs, is) (SUBLir((is), (rs)), JCm(label), _jit.x.pc)
#define jit_bmsi_i(label, rs, is) (jit_reduce(TEST, (is), (rs)), JNZm(label), _jit.x.pc)
#define jit_bmci_i(label, rs, is) (jit_reduce(TEST, (is), (rs)), JZm(label), _jit.x.pc)
#define jit_jmpi(label) (JMPm( ((unsigned long) (label))), _jit.x.pc)
#define jit_jmpr(reg) JMPsr(reg)
/* Memory */
#define jit_ldr_uc(d, rs) MOVZBLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_uc(d, s1, s2) MOVZBLmr(0, (s1), (s2), 1, (d))
#define jit_str_c(rd, rs) jit_movbrm((rs), 0, (rd), 0, 0)
#define jit_stxr_c(d1, d2, rs) jit_movbrm((rs), 0, (d1), (d2), 1)
#define jit_ldr_us(d, rs) MOVZWLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_us(d, s1, s2) MOVZWLmr(0, (s1), (s2), 1, (d))
#define jit_str_s(rd, rs) MOVWrm(jit_reg16(rs), 0, (rd), 0, 0)
#define jit_stxr_s(d1, d2, rs) MOVWrm(jit_reg16(rs), 0, (d1), (d2), 1)
#define jit_str_i(rd, rs) MOVLrm((rs), 0, (rd), 0, 0)
#define jit_stxr_i(d1, d2, rs) MOVLrm((rs), 0, (d1), (d2), 1)
/* Extra */
#define jit_nop() NOP_()
#define _jit_alignment(pc, n) (((pc ^ _MASK(4)) + 1) & _MASK(n))
#define jit_align(n) NOPi(_jit_alignment(_jit_UL(_jit.x.pc), (n)))
#if LIGHTNING_CROSS \
? LIGHTNING_TARGET == LIGHTNING_X86_64 \
: defined (__x86_64__)
#include "i386/core-64.h"
#else
#include "i386/core-32.h"
#endif
#endif /* __lightning_core_i386_h */

View File

@@ -1,356 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Support macros for the i386 math coprocessor
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2004, 2008 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
***********************************************************************/
#ifndef __lightning_fp_h
#define __lightning_fp_h
/* We really must map the x87 stack onto a flat register file. In practice,
we can provide something sensible and make it work on the x86 using the
stack like a file of eight registers.
We use six or seven registers so as to have some freedom
for floor, ceil, round, (and log, tan, atn and exp).
Not hard at all, basically play with FXCH. FXCH is mostly free,
so the generated code is not bad. Of course we special case when one
of the operands turns out to be ST0.
Here are the macros that actually do the trick. */
#define JIT_FPR_NUM 6
#define JIT_FPRET 0
#define JIT_FPR(i) (i)
#define jit_fxch(rs, op) (((rs) != 0 ? FXCHr(rs) : 0), \
op, ((rs) != 0 ? FXCHr(rs) : 0))
#define jit_fp_unary(rd, s1, op) \
((rd) == (s1) ? jit_fxch ((rd), op) \
: (rd) == 0 ? (FSTPr (0), FLDr ((s1)-1), op) \
: (FLDr ((s1)), op, FSTPr ((rd) + 1)))
#define jit_fp_binary(rd, s1, s2, op, opr) \
((rd) == (s1) ? \
((s2) == 0 ? opr(0, (rd)) \
: (s2) == (s1) ? jit_fxch((rd), op(0, 0)) \
: jit_fxch((rd), op((s2), 0))) \
: (rd) == (s2) ? \
((s1) == 0 ? op(0, (rd)) \
: jit_fxch((rd), opr((s1), 0))) \
: (FLDr (s1), op((s2)+1, 0), FSTPr((rd)+1)))
#define jit_addr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FADDrr,FADDrr)
#define jit_subr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FSUBrr,FSUBRrr)
#define jit_mulr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FMULrr,FMULrr)
#define jit_divr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FDIVrr,FDIVRrr)
#define jit_abs_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9e1))
#define jit_negr_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9e0))
#define jit_sqrt_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9fa))
/* - moves:
move FPR0 to FPR3
FST ST3
move FPR3 to FPR0
FXCH ST3
FST ST3
move FPR3 to FPR1
FLD ST3
FSTP ST2 Stack is rotated, so FPRn becomes STn+1 */
#define jit_movr_d(rd,s1) \
((s1) == (rd) ? 0 \
: (s1) == 0 ? FSTr ((rd)) \
: (rd) == 0 ? (FXCHr ((s1)), FSTr ((s1))) \
: (FLDr ((s1)), FSTPr ((rd)+1)))
/* - loads:
load into FPR0
FSTP ST0
FLD [FUBAR]
load into FPR3
FSTP ST3 Save old st0 into destination register
FLD [FUBAR]
FXCH ST3 Get back old st0
(and similarly for immediates, using the stack) */
#define jit_movi_f(rd,immf) \
(_O (0x68), \
*((float *) _jit.x.pc) = (float) immf, \
_jit.x.uc_pc += sizeof (float), \
jit_ldr_f((rd), _ESP), \
ADDLir(4, _ESP))
union jit_double_imm {
double d;
int i[2];
};
#define jit_movi_d(rd,immd) \
(_O (0x68), \
_jit.x.uc_pc[4] = 0x68, \
((union jit_double_imm *) (_jit.x.uc_pc + 5))->d = (double) immd, \
*((int *) _jit.x.uc_pc) = ((union jit_double_imm *) (_jit.x.uc_pc + 5))->i[1], \
_jit.x.uc_pc += 9, \
jit_ldr_d((rd), _ESP), \
ADDLir(8, _ESP))
#define jit_ldi_f(rd, is) \
((rd) == 0 ? (FSTPr (0), FLDSm((is), 0, 0, 0)) \
: (FLDSm((is), 0, 0, 0), FSTPr ((rd) + 1)))
#define jit_ldi_d(rd, is) \
((rd) == 0 ? (FSTPr (0), FLDLm((is), 0, 0, 0)) \
: (FLDLm((is), 0, 0, 0), FSTPr ((rd) + 1)))
#define jit_ldr_f(rd, rs) \
((rd) == 0 ? (FSTPr (0), FLDSm(0, (rs), 0, 0)) \
: (FLDSm(0, (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldr_d(rd, rs) \
((rd) == 0 ? (FSTPr (0), FLDLm(0, (rs), 0, 0)) \
: (FLDLm(0, (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxi_f(rd, rs, is) \
((rd) == 0 ? (FSTPr (0), FLDSm((is), (rs), 0, 0)) \
: (FLDSm((is), (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxi_d(rd, rs, is) \
((rd) == 0 ? (FSTPr (0), FLDLm((is), (rs), 0, 0)) \
: (FLDLm((is), (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxr_f(rd, s1, s2) \
((rd) == 0 ? (FSTPr (0), FLDSm(0, (s1), (s2), 1)) \
: (FLDSm(0, (s1), (s2), 1), FSTPr ((rd) + 1)))
#define jit_ldxr_d(rd, s1, s2) \
((rd) == 0 ? (FSTPr (0), FLDLm(0, (s1), (s2), 1)) \
: (FLDLm(0, (s1), (s2), 1), FSTPr ((rd) + 1)))
#define jit_extr_i_d(rd, rs) (PUSHLr((rs)), \
((rd) == 0 ? (FSTPr (0), FILDLm(0, _ESP, 0, 0)) \
: (FILDLm(0, _ESP, 0, 0), FSTPr ((rd) + 1))), \
POPLr((rs)))
#define jit_stxi_f(id, rd, rs) jit_fxch ((rs), FSTSm((id), (rd), 0, 0))
#define jit_stxr_f(d1, d2, rs) jit_fxch ((rs), FSTSm(0, (d1), (d2), 1))
#define jit_stxi_d(id, rd, rs) jit_fxch ((rs), FSTLm((id), (rd), 0, 0))
#define jit_stxr_d(d1, d2, rs) jit_fxch ((rs), FSTLm(0, (d1), (d2), 1))
#define jit_sti_f(id, rs) jit_fxch ((rs), FSTSm((id), 0, 0, 0))
#define jit_str_f(rd, rs) jit_fxch ((rs), FSTSm(0, (rd), 0, 0))
#define jit_sti_d(id, rs) jit_fxch ((rs), FSTLm((id), 0, 0, 0))
#define jit_str_d(rd, rs) jit_fxch ((rs), FSTLm(0, (rd), 0, 0))
/* ABI */
#define jit_retval_d(rd) FSTPr((rd) + 1)
/* Assume round to near mode */
#define jit_floorr_d_i(rd, rs) \
(FLDr (rs), jit_floor2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_ceilr_d_i(rd, rs) \
(FLDr (rs), jit_ceil2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_truncr_d_i(rd, rs) \
(FLDr (rs), jit_trunc2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_calc_diff(ofs) \
FISTLm(ofs, _ESP, 0, 0), \
FILDLm(ofs, _ESP, 0, 0), \
FSUBRPr(1), \
FSTPSm(4+ofs, _ESP, 0, 0) \
/* The real meat */
#define jit_floor2(rd, aux) \
(PUSHLr(aux), \
SUBLir(8, _ESP), \
jit_calc_diff(0), \
POPLr(rd), /* floor in rd */ \
POPLr(aux), /* x-round(x) in aux */ \
ADDLir(0x7FFFFFFF, aux), /* carry if x-round(x) < -0 */ \
SBBLir(0, rd), /* subtract 1 if carry */ \
POPLr(aux))
#define jit_ceil2(rd, aux) \
(PUSHLr(aux), \
SUBLir(8, _ESP), \
jit_calc_diff(0), \
POPLr(rd), /* floor in rd */ \
POPLr(aux), /* x-round(x) in aux */ \
TESTLrr(aux, aux), \
SETGr(jit_reg8(aux)), \
SHRLir(1, aux), \
ADCLir(0, rd), \
POPLr(aux))
/* a mingling of the two above */
#define jit_trunc2(rd, aux) \
(PUSHLr(aux), \
SUBLir(12, _ESP), \
FSTSm(0, _ESP, 0, 0), \
jit_calc_diff(4), \
POPLr(aux), \
POPLr(rd), \
TESTLrr(aux, aux), \
POPLr(aux), \
JSSm(_jit.x.pc + 11), \
ADDLir(0x7FFFFFFF, aux), /* 6 */ \
SBBLir(0, rd), /* 3 */ \
JMPSm(_jit.x.pc + 10), /* 2 */ \
TESTLrr(aux, aux), /* 2 */ \
SETGr(jit_reg8(aux)), /* 3 */ \
SHRLir(1, aux), /* 2 */ \
ADCLir(0, rd), /* 3 */ \
POPLr(aux))
/* the easy one */
#define jit_roundr_d_i(rd, rs) \
(PUSHLr(_EAX), \
jit_fxch ((rs), FISTLm(0, _ESP, 0, 0)), \
POPLr((rd)))
#define jit_fp_test(d, s1, s2, n, _and, res) \
(((s1) == 0 ? FUCOMr((s2)) : (FLDr((s1)), FUCOMPr((s2) + 1))), \
((d) != _EAX ? MOVLrr(_EAX, (d)) : 0), \
FNSTSWr(_EAX), \
SHRLir(n, _EAX), \
((_and) ? ANDLir((_and), _EAX) : MOVLir(0, _EAX)), \
res, \
((d) != _EAX ? _O (0x90 + ((d) & 7)) : 0)) /* xchg */
#define jit_fp_btest(d, s1, s2, n, _and, cmp, res) \
(((s1) == 0 ? FUCOMr((s2)) : (FLDr((s1)), FUCOMPr((s2) + 1))), \
PUSHLr(_EAX), \
FNSTSWr(_EAX), \
SHRLir(n, _EAX), \
((_and) ? ANDLir ((_and), _EAX) : 0), \
((cmp) ? CMPLir ((cmp), _EAX) : 0), \
POPLr(_EAX), \
res ((d)), \
_jit.x.pc)
#define jit_nothing_needed(x)
/* After FNSTSW we have 1 if <, 40 if =, 0 if >, 45 if unordered. Here
is how to map the values of the status word's high byte to the
conditions.
< = > unord valid values condition
gt no no yes no 0 STSW & 45 == 0
lt yes no no no 1 STSW & 45 == 1
eq no yes no no 40 STSW & 45 == 40
unord no no no yes 45 bit 2 == 1
ge no yes no no 0, 40 bit 0 == 0
unlt yes no no yes 1, 45 bit 0 == 1
ltgt yes no yes no 0, 1 bit 6 == 0
uneq no yes no yes 40, 45 bit 6 == 1
le yes yes no no 1, 40 odd parity for STSW & 41
ungt no no yes yes 0, 45 even parity for STSW & 41
unle yes yes no yes 1, 40, 45 STSW & 45 != 0
unge no yes yes yes 0, 40, 45 STSW & 45 != 1
ne yes no yes yes 0, 1, 45 STSW & 45 != 40
ord yes yes yes no 0, 1, 40 bit 2 == 0
lt, le, ungt, unge are actually computed as gt, ge, unlt, unle with
the operands swapped; it is more efficient this way. */
#define jit_gtr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, SETZr (_AL))
#define jit_ger_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 9, 0, SBBBir (-1, _AL))
#define jit_unler_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, SETNZr (_AL))
#define jit_unltr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 9, 0, ADCBir (0, _AL))
#define jit_ltr_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 8, 0x45, SETZr (_AL))
#define jit_ler_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 9, 0, SBBBir (-1, _AL))
#define jit_unger_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 8, 0x45, SETNZr (_AL))
#define jit_ungtr_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 9, 0, ADCBir (0, _AL))
#define jit_eqr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, (CMPBir (0x40, _AL), SETEr (_AL)))
#define jit_ner_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, (CMPBir (0x40, _AL), SETNEr (_AL)))
#define jit_ltgtr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 15, 0, SBBBir (-1, _AL))
#define jit_uneqr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 15, 0, ADCBir (0, _AL))
#define jit_ordr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 11, 0, SBBBir (-1, _AL))
#define jit_unordr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 11, 0, ADCBir (0, _AL))
#define jit_bgtr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JZm)
#define jit_bger_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 9, 0, 0, JNCm)
#define jit_bunler_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JNZm)
#define jit_bunltr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 9, 0, 0, JCm)
#define jit_bltr_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JZm)
#define jit_bler_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 9, 0, 0, JNCm)
#define jit_bunger_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JNZm)
#define jit_bungtr_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 9, 0, 0, JCm)
#define jit_beqr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JZm)
#define jit_bner_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JNZm)
#define jit_bltgtr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 15, 0, 0, JNCm)
#define jit_buneqr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 15, 0, 0, JCm)
#define jit_bordr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 11, 0, 0, JNCm)
#define jit_bunordr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 11, 0, 0, JCm)
#define jit_pusharg_d(rs) (jit_subi_i(JIT_SP,JIT_SP,sizeof(double)), jit_str_d(JIT_SP,(rs)))
#define jit_pusharg_f(rs) (jit_subi_i(JIT_SP,JIT_SP,sizeof(float)), jit_str_f(JIT_SP,(rs)))
#if 0
#define jit_sin() _OO(0xd9fe) /* fsin */
#define jit_cos() _OO(0xd9ff) /* fcos */
#define jit_tan() (_OO(0xd9f2), /* fptan */ \
FSTPr(0)) /* fstp st */
#define jit_atn() (_OO(0xd9e8), /* fld1 */ \
_OO(0xd9f3)) /* fpatan */
#define jit_exp() (_OO(0xd9ea), /* fldl2e */ \
FMULPr(1), /* fmulp */ \
_OO(0xd9c0), /* fld st */ \
_OO(0xd9fc), /* frndint */ \
_OO(0xdce9), /* fsubr */ \
FXCHr(1), /* fxch st(1) */ \
_OO(0xd9f0), /* f2xm1 */ \
_OO(0xd9e8), /* fld1 */ \
_OO(0xdec1), /* faddp */ \
_OO(0xd9fd), /* fscale */ \
FSTPr(1)) /* fstp st(1) */
#define jit_log() (_OO(0xd9ed), /* fldln2 */ \
FXCHr(1), /* fxch st(1) */ \
_OO(0xd9f1)) /* fyl2x */
#endif
#define jit_prepare_f(nf) (_jitl.argssize += (nf))
#define jit_prepare_d(nd) (_jitl.argssize += 2 * (nd))
#define jit_arg_f() ((_jitl.framesize += sizeof(float)) - sizeof(float))
#define jit_arg_d() ((_jitl.framesize += sizeof(double)) - sizeof(double))
#endif /* __lightning_fp_h */

View File

@@ -1,325 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Support macros for SSE floating-point math
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2006 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
***********************************************************************/
#ifndef __lightning_fp_h
#define __lightning_fp_h
#include <float.h>
#define JIT_FPR_NUM 7
#define JIT_FPRET _XMM0
#define JIT_FPR(i) (_XMM8 + (i))
#define JIT_FPTMP _XMM15
/* Either use a temporary register that is finally AND/OR/XORed with RS = RD,
or use RD as the temporary register and to the AND/OR/XOR with RS. */
#define jit_unop_tmp(rd, rs, op) \
( (rs) == (rd) \
? op((rd), JIT_FPTMP, JIT_FPTMP)) \
: op((rd), (rd), (rs)))
#define jit_unop_f(rd, rs, op) \
((rs) == (rd) ? op((rd)) : (MOVSSrr ((rs), (rd)), op((rd))))
#define jit_unop_d(rd, rs, op) \
((rs) == (rd) ? op((rd)) : (MOVSDrr ((rs), (rd)), op((rd))))
#define jit_3opc_f(rd, s1, s2, op) \
( (s1) == (rd) ? op((s2), (rd)) \
: ((s2) == (rd) ? op((s1), (rd)) \
: (MOVSSrr ((s1), (rd)), op((s2), (rd)))))
#define jit_3opc_d(rd, s1, s2, op) \
( (s1) == (rd) ? op((s2), (rd)) \
: ((s2) == (rd) ? op((s1), (rd)) \
: (MOVSDrr ((s1), (rd)), op((s2), (rd)))))
#define jit_3op_f(rd, s1, s2, op) \
( (s1) == (rd) ? op((s2), (rd)) \
: ((s2) == (rd) \
? (MOVSSrr ((rd), JIT_FPTMP), MOVSSrr ((s1), (rd)), op(JIT_FPTMP, (rd))) \
: (MOVSSrr ((s1), (rd)), op((s2), (rd)))))
#define jit_3op_d(rd, s1, s2, op) \
( (s1) == (rd) ? op((s2), (rd)) \
: ((s2) == (rd) \
? (MOVSDrr ((rd), JIT_FPTMP), MOVSDrr ((s1), (rd)), op(JIT_FPTMP, (rd))) \
: (MOVSDrr ((s1), (rd)), op((s2), (rd)))))
#define jit_addr_f(rd,s1,s2) jit_3opc_f((rd), (s1), (s2), ADDSSrr)
#define jit_subr_f(rd,s1,s2) jit_3op_f((rd), (s1), (s2), SUBSSrr)
#define jit_mulr_f(rd,s1,s2) jit_3opc_f((rd), (s1), (s2), MULSSrr)
#define jit_divr_f(rd,s1,s2) jit_3op_f((rd), (s1), (s2), DIVSSrr)
#define jit_addr_d(rd,s1,s2) jit_3opc_d((rd), (s1), (s2), ADDSDrr)
#define jit_subr_d(rd,s1,s2) jit_3op_d((rd), (s1), (s2), SUBSDrr)
#define jit_mulr_d(rd,s1,s2) jit_3opc_d((rd), (s1), (s2), MULSDrr)
#define jit_divr_d(rd,s1,s2) jit_3op_d((rd), (s1), (s2), DIVSDrr)
#define jit_movr_f(rd,rs) MOVSSrr((rs), (rd))
#define jit_movr_d(rd,rs) MOVSDrr((rs), (rd))
/* either pcmpeqd %xmm7, %xmm7 / psrld $1, %xmm7 / andps %xmm7, %RD (if RS = RD)
or pcmpeqd %RD, %RD / psrld $1, %RD / andps %RS, %RD (if RS != RD) */
#define _jit_abs_f(rd,cnst,rs) \
(PCMPEQDrr((cnst), (cnst)), PSRLDir (1, (cnst)), ANDPSrr ((rs), (rd)))
#define _jit_neg_f(rd,cnst,rs) \
(PCMPEQDrr((cnst), (cnst)), PSLLDir (31, (cnst)), XORPSrr ((rs), (rd)))
#define jit_abs_f(rd,rs) jit_unop_tmp ((rd), (rs), _jit_abs_f)
#define jit_neg_f(rd,rs) jit_unop_tmp ((rd), (rs), _jit_neg_f)
#define _jit_abs_d(rd,cnst,rs) \
(PCMPEQDrr((cnst), (cnst)), PSRLQir (1, (cnst)), ANDPDrr ((rs), (rd)))
#define _jit_neg_d(rd,cnst,rs) \
(PCMPEQDrr((cnst), (cnst)), PSLLQir (63, (cnst)), XORPDrr ((rs), (rd)))
#define jit_abs_d(rd,rs) jit_unop_tmp ((rd), (rs), _jit_abs_d)
#define jit_neg_d(rd,rs) jit_unop_tmp ((rd), (rs), _jit_neg_d)
#define jit_sqrt_d(rd,rs) SQRTSSrr((rs), (rd))
#define jit_sqrt_f(rd,rs) SQRTSDrr((rs), (rd))
#define _jit_ldi_f(d, is) MOVSSmr((is), 0, 0, 0, (d))
#define _jit_ldxi_f(d, rs, is) MOVSSmr((is), (rs), 0, 0, (d))
#define jit_ldr_f(d, rs) MOVSSmr(0, (rs), 0, 0, (d))
#define jit_ldxr_f(d, s1, s2) MOVSSmr(0, (s1), (s2), 1, (d))
#define _jit_sti_f(id, rs) MOVSSrm((rs), (id), 0, 0, 0)
#define _jit_stxi_f(id, rd, rs) MOVSSrm((rs), (id), (rd), 0, 0)
#define jit_str_f(rd, rs) MOVSSrm((rs), 0, (rd), 0, 0)
#define jit_stxr_f(d1, d2, rs) MOVSSrm((rs), 0, (d1), (d2), 1)
#define jit_ldi_f(d, is) (_u32P((long)(is)) ? _jit_ldi_f((d), (is)) : (jit_movi_l(JIT_REXTMP, (is)), jit_ldr_f((d), JIT_REXTMP)))
#define jit_sti_f(id, rs) (_u32P((long)(id)) ? _jit_sti_f((id), (rs)) : (jit_movi_l(JIT_REXTMP, (id)), jit_str_f (JIT_REXTMP, (rs))))
#define jit_ldxi_f(d, rs, is) (_u32P((long)(is)) ? _jit_ldxi_f((d), (rs), (is)) : (jit_movi_l(JIT_REXTMP, (is)), jit_ldxr_f((d), (rs), JIT_REXTMP)))
#define jit_stxi_f(id, rd, rs) (_u32P((long)(id)) ? _jit_stxi_f((id), (rd), (rs)) : (jit_movi_l(JIT_REXTMP, (id)), jit_stxr_f (JIT_REXTMP, (rd), (rs))))
#define _jit_ldi_d(d, is) MOVSDmr((is), 0, 0, 0, (d))
#define _jit_ldxi_d(d, rs, is) MOVSDmr((is), (rs), 0, 0, (d))
#define jit_ldr_d(d, rs) MOVSDmr(0, (rs), 0, 0, (d))
#define jit_ldxr_d(d, s1, s2) MOVSDmr(0, (s1), (s2), 1, (d))
#define _jit_sti_d(id, rs) MOVSDrm((rs), (id), 0, 0, 0)
#define _jit_stxi_d(id, rd, rs) MOVSDrm((rs), (id), (rd), 0, 0)
#define jit_str_d(rd, rs) MOVSDrm((rs), 0, (rd), 0, 0)
#define jit_stxr_d(d1, d2, rs) MOVSDrm((rs), 0, (d1), (d2), 1)
#define jit_ldi_d(d, is) (_u32P((long)(is)) ? _jit_ldi_d((d), (is)) : (jit_movi_l(JIT_REXTMP, (is)), jit_ldr_d((d), JIT_REXTMP)))
#define jit_sti_d(id, rs) (_u32P((long)(id)) ? _jit_sti_d((id), (rs)) : (jit_movi_l(JIT_REXTMP, (id)), jit_str_d (JIT_REXTMP, (rs))))
#define jit_ldxi_d(d, rs, is) (_u32P((long)(is)) ? _jit_ldxi_d((d), (rs), (is)) : (jit_movi_l(JIT_REXTMP, (is)), jit_ldxr_d((d), (rs), JIT_REXTMP)))
#define jit_stxi_d(id, rd, rs) (_u32P((long)(id)) ? _jit_stxi_d((id), (rd), (rs)) : (jit_movi_l(JIT_REXTMP, (id)), jit_stxr_d (JIT_REXTMP, (rd), (rs))))
#define jit_movi_f(rd,immf) \
((immf) == 0.0 ? XORSSrr ((rd), (rd)) : \
(PUSHQi (0x12345678L), \
*((float *) (_jit.x.uc_pc - 4)) = (float) immf, \
jit_ldr_f((rd), _ESP), \
ADDQir(8, _ESP)))
union jit_double_imm {
double d;
long l;
};
#define jit_movi_d(rd,immd) \
((immd) == 0.0 ? XORSDrr ((rd), (rd)) : \
(_O (0x50), \
MOVQir (0x123456789abcdef0L, _EAX), \
((union jit_double_imm *) (_jit.x.uc_pc - 8))->d = (double) immd, \
_O (0x50), jit_ldr_d((rd), _ESP), \
_O (0x58), _O (0x58)))
#define jit_extr_i_d(rd, rs) CVTSI2SDLrr((rs), (rd))
#define jit_extr_i_f(rd, rs) CVTSI2SSLrr((rs), (rd))
#define jit_extr_l_d(rd, rs) CVTSI2SDQrr((rs), (rd))
#define jit_extr_l_f(rd, rs) CVTSI2SSQrr((rs), (rd))
#define jit_extr_f_d(rd, rs) CVTSS2SDrr((rs), (rd))
#define jit_extr_d_f(rd, rs) CVTSD2SSrr((rs), (rd))
#define jit_roundr_d_i(rd, rs) CVTSD2SILrr((rs), (rd))
#define jit_roundr_f_i(rd, rs) CVTSS2SILrr((rs), (rd))
#define jit_roundr_d_l(rd, rs) CVTSD2SIQrr((rs), (rd))
#define jit_roundr_f_l(rd, rs) CVTSS2SIQrr((rs), (rd))
#define jit_truncr_d_i(rd, rs) CVTTSD2SILrr((rs), (rd))
#define jit_truncr_f_i(rd, rs) CVTTSS2SILrr((rs), (rd))
#define jit_truncr_d_l(rd, rs) CVTTSD2SIQrr((rs), (rd))
#define jit_truncr_f_l(rd, rs) CVTTSS2SIQrr((rs), (rd))
#define jit_ceilr_f_i(rd, rs) do { \
jit_roundr_f_i ((rd), (rs)); \
jit_extr_i_f (JIT_FPTMP, (rd)); \
UCOMISSrr ((rs), JIT_FPTMP); \
ADCLir (0, (rd)); \
} while (0)
#define jit_ceilr_d_i(rd, rs) do { \
jit_roundr_d_i ((rd), (rs)); \
jit_extr_i_d (JIT_FPTMP, (rd)); \
UCOMISDrr ((rs), JIT_FPTMP); \
ADCLir (0, (rd)); \
} while (0)
#define jit_ceilr_f_l(rd, rs) do { \
jit_roundr_f_l ((rd), (rs)); \
jit_extr_l_f (JIT_FPTMP, (rd)); \
UCOMISSrr ((rs), JIT_FPTMP); \
ADCLir (0, (rd)); \
} while (0)
#define jit_ceilr_d_l(rd, rs) do { \
jit_roundr_d_l ((rd), (rs)); \
jit_extr_l_d (JIT_FPTMP, (rd)); \
UCOMISDrr ((rs), JIT_FPTMP); \
ADCLir (0, (rd)); \
} while (0)
#define jit_floorr_f_i(rd, rs) do { \
jit_roundr_f_i ((rd), (rs)); \
jit_extr_i_f (JIT_FPTMP, (rd)); \
UCOMISSrr (JIT_FPTMP, (rs)); \
SBBLir (0, (rd)); \
} while (0)
#define jit_floorr_d_i(rd, rs) do { \
jit_roundr_d_i ((rd), (rs)); \
jit_extr_i_d (JIT_FPTMP, (rd)); \
UCOMISDrr (JIT_FPTMP, (rs)); \
SBBLir (0, (rd)); \
} while (0)
#define jit_floorr_f_l(rd, rs) do { \
jit_roundr_f_l ((rd), (rs)); \
jit_extr_l_f (JIT_FPTMP, (rd)); \
UCOMISSrr (JIT_FPTMP, (rs)); \
SBBLir (0, (rd)); \
} while (0)
#define jit_floorr_d_l(rd, rs) do { \
jit_roundr_d_l ((rd), (rs)); \
jit_extr_l_d (JIT_FPTMP, (rd)); \
UCOMISDrr (JIT_FPTMP, (rs)); \
SBBLir (0, (rd)); \
} while (0)
#define jit_bltr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JAm ((d)), _jit.x.pc)
#define jit_bler_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JAEm ((d)), _jit.x.pc)
#define jit_beqr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), _OO (0x7a06), JEm ((d)), _jit.x.pc)
#define jit_bner_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), _OO (0x7a02), _OO (0x7405), JMPm (((d))), _jit.x.pc) /* JP to JMP, JZ past JMP */
#define jit_bger_f(d, s1, s2) (UCOMISSrr ((s2), (s1)), JAEm ((d)), _jit.x.pc)
#define jit_bgtr_f(d, s1, s2) (UCOMISSrr ((s2), (s1)), JAm ((d)), _jit.x.pc)
#define jit_bunltr_f(d, s1, s2) (UCOMISSrr ((s2), (s1)), JNAEm ((d)), _jit.x.pc)
#define jit_bunler_f(d, s1, s2) (UCOMISSrr ((s2), (s1)), JNAm ((d)), _jit.x.pc)
#define jit_buneqr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JEm ((d)), _jit.x.pc)
#define jit_bltgtr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JNEm ((d)), _jit.x.pc)
#define jit_bunger_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JNAm ((d)), _jit.x.pc)
#define jit_bungtr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JNAEm ((d)), _jit.x.pc)
#define jit_bordr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JNPm ((d)), _jit.x.pc)
#define jit_bunordr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JPm ((d)), _jit.x.pc)
#define jit_bltr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JAm ((d)), _jit.x.pc)
#define jit_bler_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JAEm ((d)), _jit.x.pc)
#define jit_beqr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), _OO (0x7a06), JEm ((d)), _jit.x.pc)
#define jit_bner_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), _OO (0x7a02), _OO (0x7405), JMPm (((d))), _jit.x.pc) /* JP to JMP, JZ past JMP */
#define jit_bger_d(d, s1, s2) (UCOMISDrr ((s2), (s1)), JAEm ((d)), _jit.x.pc)
#define jit_bgtr_d(d, s1, s2) (UCOMISDrr ((s2), (s1)), JAm ((d)), _jit.x.pc)
#define jit_bunltr_d(d, s1, s2) (UCOMISDrr ((s2), (s1)), JNAEm ((d)), _jit.x.pc, _jit.x.pc)
#define jit_bunler_d(d, s1, s2) (UCOMISDrr ((s2), (s1)), JNAm ((d)), _jit.x.pc)
#define jit_buneqr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JEm ((d)), _jit.x.pc)
#define jit_bltgtr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JNEm ((d)), _jit.x.pc)
#define jit_bunger_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JNAm ((d)), _jit.x.pc)
#define jit_bungtr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JNAEm ((d)), _jit.x.pc)
#define jit_bordr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JNPm ((d)), _jit.x.pc)
#define jit_bunordr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JPm ((d)), _jit.x.pc)
#define jit_ltr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETAr (jit_reg8((d))))
#define jit_ler_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETAEr (jit_reg8((d))))
#define jit_eqr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), _OO(0x7a03), SETEr (jit_reg8((d))))
#define jit_ner_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), MOVLir (1, (d)), _OO(0x7a03), SETNEr (jit_reg8((d))))
#define jit_ger_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s2), (s1)), SETAEr (jit_reg8((d))))
#define jit_gtr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s2), (s1)), SETAr (jit_reg8((d))))
#define jit_unltr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s2), (s1)), SETNAEr (jit_reg8((d))))
#define jit_unler_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s2), (s1)), SETNAr (jit_reg8((d))))
#define jit_uneqr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETEr (jit_reg8((d))))
#define jit_ltgtr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETNEr (jit_reg8((d))))
#define jit_unger_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETNAr (jit_reg8((d))))
#define jit_ungtr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETNAEr (jit_reg8((d))))
#define jit_ordr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETNPr (jit_reg8((d))))
#define jit_unordr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETPr (jit_reg8((d))))
#define jit_ltr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETAr (jit_reg8((d))))
#define jit_ler_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETAEr (jit_reg8((d))))
#define jit_eqr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), _OO(0x7a03), SETEr (jit_reg8((d))))
#define jit_ner_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), MOVLir (1, (d)), _OO(0x7a03), SETNEr (jit_reg8((d))))
#define jit_ger_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s2), (s1)), SETAEr (jit_reg8((d))))
#define jit_gtr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s2), (s1)), SETAr (jit_reg8((d))))
#define jit_unltr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s2), (s1)), SETNAEr (jit_reg8((d))))
#define jit_unler_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s2), (s1)), SETNAr (jit_reg8((d))))
#define jit_uneqr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETEr (jit_reg8((d))))
#define jit_ltgtr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETNEr (jit_reg8((d))))
#define jit_unger_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETNAr (jit_reg8((d))))
#define jit_ungtr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETNAEr (jit_reg8((d))))
#define jit_ordr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETNPr (jit_reg8((d))))
#define jit_unordr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETPr (jit_reg8((d))))
#define jit_prepare_f(num) ((_jitl.nextarg_putfp + (num) > JIT_FP_ARG_MAX \
? (_jitl.argssize += _jitl.nextarg_putfp + (num) - JIT_FP_ARG_MAX, \
_jitl.fprssize = JIT_FP_ARG_MAX) \
: (_jitl.fprssize += (num))), \
_jitl.nextarg_putfp += (num))
#define jit_prepare_d(num) ((_jitl.nextarg_putfp + (num) > JIT_FP_ARG_MAX \
? (_jitl.argssize += _jitl.nextarg_putfp + (num) - JIT_FP_ARG_MAX, \
_jitl.fprssize = JIT_FP_ARG_MAX) \
: (_jitl.fprssize += (num))), \
_jitl.nextarg_putfp += (num))
#define jit_arg_f() (_jitl.nextarg_getfp < JIT_FP_ARG_MAX \
? _jitl.nextarg_getfp++ \
: ((_jitl.framesize += sizeof(double)) - sizeof(double)))
#define jit_arg_d() (_jitl.nextarg_getfp < JIT_FP_ARG_MAX \
? _jitl.nextarg_getfp++ \
: ((_jitl.framesize += sizeof(double)) - sizeof(double)))
#define jit_getarg_f(reg, ofs) ((ofs) < JIT_FP_ARG_MAX \
? jit_movr_f((reg), _XMM0 + (ofs)) \
: jit_ldxi_f((reg), JIT_FP, (ofs)))
#define jit_getarg_d(reg, ofs) ((ofs) < JIT_FP_ARG_MAX \
? jit_movr_d((reg), _XMM0 + (ofs)) \
: jit_ldxi_d((reg), JIT_FP, (ofs)))
#define jit_pusharg_f(rs) (--_jitl.nextarg_putfp >= JIT_FP_ARG_MAX \
? (SUBQir(sizeof(double), JIT_SP), jit_str_f(JIT_SP,(rs))) \
: jit_movr_f(_XMM0 + _jitl.nextarg_putfp, (rs)))
#define jit_pusharg_d(rs) (--_jitl.nextarg_putfp >= JIT_FP_ARG_MAX \
? (SUBQir(sizeof(double), JIT_SP), jit_str_d(JIT_SP,(rs))) \
: jit_movr_d(_XMM0 + _jitl.nextarg_putfp, (rs)))
#endif /* __lightning_fp_h */

View File

@@ -1,45 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Floating-point support (i386)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2008 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
***********************************************************************/
#ifndef __lightning_fp_i386_h
#define __lightning_fp_i386_h
#if LIGHTNING_CROSS \
? LIGHTNING_TARGET == LIGHTNING_X86_64 \
: defined (__x86_64__)
#include "i386/fp-64.h"
#else
#include "i386/fp-32.h"
#endif
#endif /* __lightning_fp_i386_h */

View File

@@ -1,92 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer inline functions (i386)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
***********************************************************************/
#ifndef __lightning_funcs_h
#define __lightning_funcs_h
#if defined(__linux__) || defined(__APPLE__)
#include <unistd.h>
#include <sys/mman.h>
#endif
static void
jit_flush_code(void *dest, void *end)
{
/* On the x86, the PROT_EXEC bits are not handled by the MMU.
However, the kernel can emulate this by setting the code
segment's limit to the end address of the highest page
whose PROT_EXEC bit is set.
Linux kernels that do so and that disable by default the
execution of the data and stack segment are becoming more
and more common (Fedora, for example), so we implement our
jit_flush_code as an mprotect. */
#if defined(__linux__) || defined(__APPLE__)
static unsigned long prev_page = 0, prev_length = 0;
unsigned long page, length;
#ifdef PAGESIZE
const int page_size = PAGESIZE;
#else
static int page_size = -1;
if (page_size == -1)
page_size = getpagesize();
#endif
page = (long) dest & ~(page_size - 1);
length = ((char *) end - (char *) page + page_size - 1) & ~(page_size - 1);
/* Simple-minded attempt at optimizing the common case where a single
chunk of memory is used to compile multiple functions. */
if (page >= prev_page && page + length <= prev_page + prev_length)
return;
mprotect ((void *) page, length, PROT_READ | PROT_WRITE | PROT_EXEC);
/* See if we can extend the previously mprotect'ed memory area towards
higher addresses: the starting address remains the same as before. */
if (page >= prev_page && page <= prev_page + prev_length)
prev_length = page + length - prev_page;
/* See if we can extend the previously mprotect'ed memory area towards
lower addresses: the highest address remains the same as before. */
else if (page < prev_page && page + length >= prev_page
&& page + length <= prev_page + prev_length)
prev_length += prev_page - page, prev_page = page;
/* Nothing to do, replace the area. */
else
prev_page = page, prev_length = length;
#endif
}
#endif /* __lightning_funcs_h */

View File

@@ -1,647 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Run-time assembler for the PowerPC
*
***********************************************************************/
/***********************************************************************
*
* Copyright 1999, 2000, 2001, 2002 Ian Piumarta
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_asm_h
#define __lightning_asm_h
/* <imm> = [0-9]+ | (.+) -> add i, one parameter (imm)
* <reg> = r<imm> -> add r, one parameter (imm)
* <mem> = <imm>(<reg>) -> add m, two parameters (imm,reg)
* <idx> = <reg>(<reg>) -> add x, two parameters (reg,reg)
*
* `x' operands have two forms. For example `stwu source, rega(regb)'
* could be written as either
* STWUrx(source, rega, regb)
* or
* STWUXrrr(source, rega, regb)
*/
/*** a brief NOTE about halfwords and "shifted" operands
*
* LOGICAL insns require UNSIGNED args in 0..65535, whether or not shifted
*
* ARITHMETIC insns require SIGNED args in -32768..32767, even when shifted
*
* as a special case: "lis/addis" also accepts UNSIGNED arguments in
* 0..65535 since it is often used immediately before "ori" to load a 32-bit
* constant (this is consistent with the GNU rs/6000 and PowerPC assemblers)
*
* thus: lis rD, expression@hi
* ori rD, rD, expression@lo ; load 32-bit constant
*/
typedef unsigned int jit_insn;
#ifndef LIGHTNING_DEBUG
#define _cr0 0
#define _cr1 1
#define _cr2 2
#define _cr3 3
#define _cr4 4
#define _cr5 5
#define _cr6 6
#define _cr7 7
#define _lt 0
#define _gt 1
#define _eq 2
#define _so 3
#define _un 3
#define _d16(D) (_ck_d(16,(_jit_UL(D)-_jit_UL(_jit.x.pc))) & ~3)
#define _d26(D) (_ck_d(26,(_jit_UL(D)-_jit_UL(_jit.x.pc))) & ~3)
/* primitive instruction forms [1, Section A.4] */
#define _FB( OP, BD,AA,LK ) (_jit_I_noinc((_u6(OP)<<26)| _d26(BD)| (_u1(AA)<<1)|_u1(LK)), _jit.x.pc++, 0)
#define _FBA( OP, BD,AA,LK ) _jit_I((_u6(OP)<<26)| (_u26(BD)&~3)| (_u1(AA)<<1)|_u1(LK))
#define _BB( OP,BO,BI, BD,AA,LK ) (_jit_I_noinc((_u6(OP)<<26)|(_u5(BO)<<21)|(_u5(BI)<<16)| _d16(BD)| (_u1(AA)<<1)|_u1(LK)), _jit.x.pc++, 0)
#define _D( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _s16(DD) )
#define _Du( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _u16(DD) )
#define _Ds( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _su16(DD) )
#define _X( OP,RD,RA,RB, XO,RC ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)|( _u5(RB)<<11)| (_u10(XO)<<1)|_u1(RC))
#define _XL( OP,BO,BI, XO,LK ) _jit_I((_u6(OP)<<26)|(_u5(BO)<<21)|(_u5(BI)<<16)|( _u5(00)<<11)| (_u10(XO)<<1)|_u1(LK))
#define _XFX( OP,RD, SR,XO ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)| (_u10(SR)<<11)| (_u10(XO)<<1)|_u1(00))
#define _XO( OP,RD,RA,RB,OE,XO,RC ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)|( _u5(RB)<<11)|(_u1(OE)<<10)|( _u9(XO)<<1)|_u1(RC))
#define _M( OP,RS,RA,SH,MB,ME,RC ) _jit_I((_u6(OP)<<26)|(_u5(RS)<<21)|(_u5(RA)<<16)|( _u5(SH)<<11)|(_u5(MB)<< 6)|( _u5(ME)<<1)|_u1(RC))
/* special purpose registers (form XFX) [1, Section 8.2, page 8-138] */
#define SPR_LR ((8<<5)|(0))
/* +++ intrinsic instructions */
#define ADDrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 266, 0)
#define ADD_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 266, 1)
#define ADDCrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 10, 0)
#define ADDC_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 10, 1)
#define ADDErrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 138, 0)
#define ADDE_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 138, 1)
#define ADDOrrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 266, 0)
#define ADDO_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 266, 1)
#define ADDIrri(RD, RA, IMM) _D (14, RD, RA, IMM)
#define ADDICrri(RD, RA, IMM) _D (12, RD, RA, IMM)
#define ADDIC_rri(RD, RA, IMM) _D (13, RD, RA, IMM)
#define ADDISrri(RD, RA, IMM) _Ds (15, RD, RA, IMM)
#define ANDrrr(RA, RS, RB) _X (31, RS, RA, RB, 28, 0)
#define AND_rrr(RA, RS, RB) _X (31, RS, RA, RB, 28, 1)
#define ANDCrrr(RA, RS, RB) _X (31, RS, RA, RB, 60, 0)
#define ANDC_rrr(RA, RS, RB) _X (31, RS, RA, RB, 60, 1)
#define ANDI_rri(RA, RS, IMM) _Du (28, RS, RA, IMM)
#define ANDIS_rri(RA, RS, IMM) _Du (29, RS, RA, IMM)
#define Bi(BD) _FB (18, BD, 0, 0)
#define BAi(BD) _FBA (18, BD, 1, 0)
#define BLi(BD) _FB (18, BD, 0, 1)
#define BLAi(BD) _FBA (18, BD, 1, 1)
#define BCiii(BO,BI,BD) _BB (16, BO, BI, BD, 0, 0)
#define BCAiii(BO,BI,BD) _BB (16, BO, BI, BD, 1, 0)
#define BCLiii(BO,BI,BD) _BB (16, BO, BI, BD, 0, 1)
#define BCLAiii(BO,BI,BD) _BB (16, BO, BI, BD, 1, 1)
#define BCCTRii(BO,BI) _XL (19, BO, BI, 528, 0)
#define BCCTRLii(BO,BI) _XL (19, BO, BI, 528, 1)
#define BCLRii(BO,BI) _XL (19, BO, BI, 16, 0)
#define BCLRLii(BO,BI) _XL (19, BO, BI, 16, 1)
#define CMPiirr(CR, LL, RA, RB) _X (31, ((CR)<<2)|(LL), RA, RB, 0, 0)
#define CMPIiiri(CR, LL, RA, IMM) _D (11, ((CR)<<2)|(LL), RA, IMM)
#define CMPLiirr(CR, LL, RA, RB) _X (31, ((CR)<<2)|(LL), RA, RB, 32, 0)
#define CMPLIiiri(CR, LL, RA, IMM) _D (10, ((CR)<<2)|(LL), RA, IMM)
#define CRANDiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 257, 0)
#define CRANDCiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 129, 0)
#define CREQViii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 289, 0)
#define CRNANDiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 225, 0)
#define CRNORiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 33, 0)
#define CRORiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 449, 0)
#define CRORCiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 417, 0)
#define CRXORiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 193, 0)
#define DCBSTrr(RA,RB) _X (31, 00, RA, RB, 54, 0)
#define DIVWrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 491, 0)
#define DIVW_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 491, 1)
#define DIVWOrrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 491, 0)
#define DIVWO_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 491, 1)
#define DIVWUrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 459, 0)
#define DIVWU_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 459, 1)
#define DIVWUOrrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 459, 0)
#define DIVWUO_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 459, 1)
#define EQVrrr(Ra,RS,RB) _X (31, RS, RA, RB, 284, 0)
#define EQV_rrr(Ra,RS,RB) _X (31, RS, RA, RB, 284, 1)
#define EXTSBrr(RA,RS) _X (31, RS, RA, 0, 954, 0)
#define EXTSB_rr(RA,RS) _X (31, RS, RA, 0, 954, 1)
#define EXTSHrr(RA,RS) _X (31, RS, RA, 0, 922, 0)
#define EXTSH_rr(RA,RS) _X (31, RS, RA, 0, 922, 1)
#define ICBIrr(RA,RB) _X (31, 00, RA, RB, 982, 0)
#define ISYNC() _X (19, 00, 00, 00, 150, 0)
#define LBZrm(RD,ID,RA) _D (34, RD, RA, ID)
#define LBZUrm(RD,ID,RA) _D (35, RD, RA, ID)
#define LBZUXrrr(RD,RA,RB) _X (31, RD, RA, RB, 119, 0)
#define LBZXrrr(RD,RA,RB) _X (31, RD, RA, RB, 87, 0)
#define LHArm(RD,ID,RA) _D (42, RD, RA, ID)
#define LHAUrm(RD,ID,RA) _D (43, RD, RA, ID)
#define LHAUXrrr(RD,RA,RB) _X (31, RD, RA, RB, 375, 0)
#define LHAXrrr(RD,RA,RB) _X (31, RD, RA, RB, 343, 0)
#define LHBRXrrr(RD,RA,RB) _X (31, RD, RA, RB, 790, 0)
#define LHZrm(RD,ID,RA) _D (40, RD, RA, ID)
#define LHZUrm(RD,ID,RA) _D (41, RD, RA, ID)
#define LHZUXrrr(RD,RA,RB) _X (31, RD, RA, RB, 311, 0)
#define LHZXrrr(RD,RA,RB) _X (31, RD, RA, RB, 279, 0)
#define LMWrm(RD,ID,RA) _D (46, RD, RA, ID)
#define LWBRXrrr(RD,RA,RB) _X (31, RD, RA, RB, 534, 0)
#define LWZrm(RD, DISP, RA) _D (32, RD, RA, DISP)
#define LWZUrm(RD, DISP, RA) _D (33, RD, RA, DISP)
#define LWZUXrrr(RD, RA, RB) _X (31, RD, RA, RB, 56, 0)
#define LWZXrrr(RD, RA, RB) _X (31, RD, RA, RB, 23, 0)
#define MCRFii(CD,CS) _X (19, ((CD)<<2), ((CS)<<2), 0, 0, 0)
#define MFCRr(RD) _X (31, RD, 0, 0, 19, 0)
#define MCRXRi(RD) _XFX (31, (RD)<<2, 0, 512)
#define MFSPRri(RD, SPR) _XFX (31, RD, (SPR)<<5, 339)
#define MTSPRir(SPR, RS) _XFX (31, RS, (SPR)<<5, 467)
#define MULHWrrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 75, 0)
#define MULHW_rrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 75, 1)
#define MULHWUrrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 11, 0)
#define MULHWU_rrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 11, 1)
#define MULLIrri(RD,RA,IM) _D (07, RD, RA, IM)
#define MULLWrrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 235, 0)
#define MULLW_rrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 235, 1)
#define MULLWOrrr(RD,RA,RB) _XO (31, RD, RA, RB, 1, 235, 0)
#define MULLWO_rrr(RD,RA,RB) _XO (31, RD, RA, RB, 1, 235, 1)
#define NANDrrr(RA,RS,RB) _X (31, RS, RA, RB, 476, 0)
#define NAND_rrr(RA,RS,RB) _X (31, RS, RA, RB, 476, 1)
#define NEGrr(RD,RA) _XO (31, RD, RA, 0, 0, 104, 0)
#define NEG_rr(RD,RA) _XO (31, RD, RA, 0, 0, 104, 1)
#define NEGOrr(RD,RA) _XO (31, RD, RA, 0, 1, 104, 0)
#define NEGO_rr(RD,RA) _XO (31, RD, RA, 0, 1, 104, 1)
#define NORrrr(RA,RS,RB) _X (31, RS, RA, RB, 124, 0)
#define NOR_rrr(RA,RS,RB) _X (31, RS, RA, RB, 124, 1)
#define ORrrr(RA,RS,RB) _X (31, RS, RA, RB, 444, 0)
#define OR_rrr(RA,RS,RB) _X (31, RS, RA, RB, 444, 1)
#define ORCrrr(RA,RS,RB) _X (31, RS, RA, RB, 412, 0)
#define ORC_rrr(RA,RS,RB) _X (31, RS, RA, RB, 412, 1)
#define ORIrri(RA,RS,IM) _Du (24, RS, RA, IM)
#define ORISrri(RA,RS,IM) _Du (25, RS, RA, IM)
#define RLWIMIrriii(RA,RS,SH,MB,ME) _M (20, RS, RA, SH, MB, ME, 0)
#define RLWIMI_rriii(RA,RS,SH,MB,ME) _M (20, RS, RA, SH, MB, ME, 1)
#define RLWINMrriii(RA,RS,SH,MB,ME) _M (21, RS, RA, SH, MB, ME, 0)
#define RLWINM_rriii(RA,RS,SH,MB,ME) _M (21, RS, RA, SH, MB, ME, 1)
#define RLWNMrrrii(RA,RS,RB,MB,ME) _M (23, RS, RA, RB, MB, ME, 0)
#define RLWNM_rrrii(RA,RS,RB,MB,ME) _M (23, RS, RA, RB, MB, ME, 1)
#define SLWrrr(RA,RS,RB) _X (31, RS, RA, RB, 24, 0)
#define SLW_rrr(RA,RS,RB) _X (31, RS, RA, RB, 24, 1)
#define SRAWrrr(RA,RS,RB) _X (31, RS, RA, RB, 792, 0)
#define SRAW_rrr(RA,RS,RB) _X (31, RS, RA, RB, 792, 1)
#define SRAWIrri(RD, RS, SH) _X (31, RS, RD, SH, 824, 0)
#define SRAWI_rri(RD, RS, SH) _X (31, RS, RD, SH, 824, 1)
#define SRWrrr(RA,RS,RB) _X (31, RS, RA, RB, 536, 0)
#define SRW_rrr(RA,RS,RB) _X (31, RS, RA, RB, 536, 1)
#define STBrm(RS,ID,RA) _D (38, RS, RA, ID)
#define STBUrm(RS,ID,RA) _D (39, RS, RA, ID)
#define STBUXrrr(RS,RA,RB) _X (31, RS, RA, RB, 247, 0)
#define STBXrrr(RS,RA,RB) _X (31, RS, RA, RB, 215, 0)
#define STHrm(RS,ID,RA) _D (44, RS, RA, ID)
#define STHUrm(RS,ID,RA) _D (45, RS, RA, ID)
#define STHBRXrrr(RS,RA,RB) _X (31, RS, RA, RB, 918, 0)
#define STHUXrrr(RS,RA,RB) _X (31, RS, RA, RB, 439, 0)
#define STHXrrr(RS,RA,RB) _X (31, RS, RA, RB, 407, 0)
#define STMWrm(RS,ID,RA) _D (47, RS, RA, ID)
#define STWrm(RS,ID,RA) _D (36, RS, RA, ID)
#define STWBRXrrr(RS,RA,RB) _X (31, RS, RA, RB, 662, 0)
#define STWCXrrr(RS,RA,RB) _X (31, RS, RA, RB, 150, 0)
#define STWCX_rrr(RS,RA,RB) _X (31, RS, RA, RB, 150, 1)
#define STWUrm(RS,ID,RA) _D (37, RS, RA, ID)
#define STWUXrrr(RS,RA,RB) _X (31, RS, RA, RB, 183, 0)
#define STWXrrr(RS,RA,RB) _X (31, RS, RA, RB, 151, 0)
#define SUBFrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 40, 0)
#define SUBF_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 40, 1)
#define SUBFrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 40, 0)
#define SUBF_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 40, 1)
#define SUBFErrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 136, 0)
#define SUBFE_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 136, 1)
#define SUBFCrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 8, 0)
#define SUBFC_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 8, 1)
#define SUBFCOrrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 8, 0)
#define SUBFCO_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 8, 1)
#define SUBFICrri(RD, RA, IMM) _D (8, RD, RA, IMM)
#define ADDrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 266, 0)
#define ADDOrrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 266, 0)
#define ADDIrri(RD, RA, IMM) _D (14, RD, RA, IMM)
#define ADDISrri(RD, RA, IMM) _Ds (15, RD, RA, IMM)
#define SYNC() _X (31, 00, 00, 00, 598, 0)
#define TWirr(TO,RA,RB) _X (31, TO, RA, RB, 4, 0)
#define TWIiri(TO,RA,IM) _D (03, TO, RA, IM)
#define XORrrr(RA,RS,RB) _X (31, RS, RA, RB, 316, 0)
#define XOR_rrr(RA,RS,RB) _X (31, RS, RA, RB, 316, 1)
#define XORIrri(RA,RS,IM) _Du (26, RS, RA, IM)
#define XORISrri(RA,RS,IM) _Du (27, RS, RA, IM)
/* simplified mnemonics [1, Appendix F] */
#define MOVEIri2(R,H,L) (LISri(R,H), (L ? ORIrri(R,R,L) : 0))
#define MOVEIri(R,I) (_siP(16,I) ? LIri(R,I) : \
MOVEIri2(R, _HI(I), _LO(I)) )
#define SUBIrri(RD,RA,IM) ADDIrri(RD,RA,-_LO((IM))) /* [1, Section F.2.1] */
#define SUBISrri(RD,RA,IM) ADDISrri(RD,RA,-_LO((IM)))
#define SUBICrri(RD,RA,IM) ADDICrri(RD,RA,-_LO((IM)))
#define SUBIC_rri(RD,RA,IM) ADDIC_rri(RD,RA,-_LO((IM)))
#define SUBrrr(RD,RA,RB) SUBFrrr(RD,RB,RA) /* [1, Section F.2.2] */
#define SUBOrrr(RD,RA,RB) SUBFOrrr(RD,RB,RA)
#define SUB_rrr(RD,RA,RB) SUBF_rrr(RD,RB,RA)
#define SUBCrrr(RD,RA,RB) SUBFCrrr(RD,RB,RA)
#define SUBCOrrr(RD,RA,RB) SUBFCOrrr(RD,RB,RA)
#define SUBC_rrr(RD,RA,RB) SUBFC_rrr(RD,RB,RA)
#define SUBErrr(RD,RA,RB) SUBFErrr(RD,RB,RA)
#define SUBE_rrr(RD,RA,RB) SUBFE_rrr(RD,RB,RA)
#define CMPWIiri(C,RA,IM) CMPIiiri(C,0,RA,IM) /* [1, Table F-2] */
#define CMPWirr(C,RA,RB) CMPiirr(C,0,RA,RB)
#define CMPLWIiri(C,RA,IM) CMPLIiiri(C,0,RA,IM)
#define CMPLWirr(C,RA,RB) CMPLiirr(C,0,RA,RB)
#define CMPWIri(RA,IM) CMPWIiri(0,RA,IM) /* with implicit _cr0 */
#define CMPWrr(RA,RB) CMPWirr(0,RA,RB)
#define CMPLWIri(RA,IM) CMPLWIiri(0,RA,IM)
#define CMPLWrr(RA,RB) CMPLWirr(0,RA,RB)
#define EXTLWIrrii(RA,RS,N,B) RLWINMrriii(RA, RS, B, 0, (N)-1) /* [1, Table F-3] */
#define EXTRWIrrii(RA,RS,N,B) RLWINMrriii(RA, RS, (B)+(N), 32-(N), 31)
#define INSLWIrrii(RA,RS,N,B) RLWIMIrriii(RA, RS, 32-(B), B, (B)+(N)-1)
#define INSRWIrrii(RA,RS,N,B) RLWIMIrriii(RA, RS, 32-((B)+(N)), B, (B)+(N)-1)
#define ROTLWIrri(RA,RS,N) RLWINMrriii(RA, RS, N, 0, 31)
#define ROTRWIrri(RA,RS,N) RLWINMrriii(RA, RS, 32-(N), 0, 31)
#define ROTLWrrr(RA,RS,RB) RLWNMrrrii( RA, RS, RB, 0, 31)
#define SLWIrri(RA,RS,N) RLWINMrriii(RA, RS, N, 0, 31-(N))
#define SRWIrri(RA,RS,N) RLWINMrriii(RA, RS, 32-(N), N, 31)
#define CLRLWIrri(RA,RS,N) RLWINMrriii(RA, RS, 0, N, 31)
#define CLRRWIrri(RA,RS,N) RLWINMrriii(RA, RS, 0, 0, 31-(N))
#define CLRLSLWIrrii(RA,RS,B,N) RLWINMrriii(RA, RS, N, (B)-(N), 31-(N))
/* 9 below inverts the branch condition and the branch prediction.
* This has an incestuous knowledge of JIT_AUX */
#define BC_EXT(A, C, D) (_siP(16, _jit_UL(D)-_jit_UL(_jit.x.pc)) \
? BCiii((A), (C), (D)) \
: (BCiii((A)^9, (C), _jit.x.pc+5), \
LISri(JIT_AUX,_HI(D)), \
ORIrri(JIT_AUX,JIT_AUX,_LO(D)), \
MTLRr(JIT_AUX), BLR() ))
#define B_EXT(D) (_siP(16, _jit_UL(D)-_jit_UL(_jit.x.pc)) \
? Bi((D)) \
: (LISri(JIT_AUX,_HI(D)), \
ORIrri(JIT_AUX,JIT_AUX,_LO(D)), \
MTLRr(JIT_AUX), BLR()) )
#define BTii(C,D) BC_EXT(12, C, D) /* [1, Table F-5] */
#define BFii(C,D) BC_EXT( 4, C, D)
#define BDNZi(D) BCiii(16, 0, D)
#define BDNZTii(C,D) BC_EXT( 8, C, D)
#define BDNZFii(C,D) BC_EXT( 0, C, D)
#define BDZi(D) BCiii(18, 0, D)
#define BDZTii(C,D) BC_EXT(10, C, D)
#define BDZFii(C,D) BC_EXT( 2, C, D)
#define BCTR() BCCTRii(20, 0) /* [1, Table F-6] */
#define BCTRL() BCCTRLii(20, 0)
#define BLR() BCLRii(20, 0) /* [1, Table F-6] */
#define BLRL() BCLRLii(20, 0)
#define BLTLRi(CR) BCLRii(12, ((CR)<<2)+0) /* [1, Table F-10] */
#define BLELRi(CR) BCLRii( 4, ((CR)<<2)+1)
#define BEQLRi(CR) BCLRii(12, ((CR)<<2)+2)
#define BGELRi(CR) BCLRii( 4, ((CR)<<2)+0)
#define BGTLRi(CR) BCLRii(12, ((CR)<<2)+1)
#define BNLLRi(CR) BCLRii( 4, ((CR)<<2)+0)
#define BNELRi(CR) BCLRii( 4, ((CR)<<2)+2)
#define BNGLRi(CR) BCLRii( 4, ((CR)<<2)+1)
#define BSOLRi(CR) BCLRii(12, ((CR)<<2)+3)
#define BNSLRi(CR) BCLRii( 4, ((CR)<<2)+3)
#define BUNLRi(CR) BCLRii(12, ((CR)<<2)+3)
#define BNULRi(CR) BCLRii( 4, ((CR)<<2)+3)
#define BLTLRLi(CR) BCLRLii(12, ((CR)<<2)+0) /* [1, Table F-10] */
#define BLELRLi(CR) BCLRLii( 4, ((CR)<<2)+1)
#define BEQLRLi(CR) BCLRLii(12, ((CR)<<2)+2)
#define BGELRLi(CR) BCLRLii( 4, ((CR)<<2)+0)
#define BGTLRLi(CR) BCLRLii(12, ((CR)<<2)+1)
#define BNLLRLi(CR) BCLRLii( 4, ((CR)<<2)+0)
#define BNELRLi(CR) BCLRLii( 4, ((CR)<<2)+2)
#define BNGLRLi(CR) BCLRLii( 4, ((CR)<<2)+1)
#define BSOLRLi(CR) BCLRLii(12, ((CR)<<2)+3)
#define BNSLRLi(CR) BCLRLii( 4, ((CR)<<2)+3)
#define BUNLRLi(CR) BCLRLii(12, ((CR)<<2)+3)
#define BNULRLi(CR) BCLRLii( 4, ((CR)<<2)+3)
#define BLTCTRi(CR) BCCTRii(12, ((CR)<<2)+0) /* [1, Table F-10] */
#define BLECTRi(CR) BCCTRii( 4, ((CR)<<2)+1)
#define BEQCTRi(CR) BCCTRii(12, ((CR)<<2)+2)
#define BGECTRi(CR) BCCTRii( 4, ((CR)<<2)+0)
#define BGTCTRi(CR) BCCTRii(12, ((CR)<<2)+1)
#define BNLCTRi(CR) BCCTRii( 4, ((CR)<<2)+0)
#define BNECTRi(CR) BCCTRii( 4, ((CR)<<2)+2)
#define BNGCTRi(CR) BCCTRii( 4, ((CR)<<2)+1)
#define BSOCTRi(CR) BCCTRii(12, ((CR)<<2)+3)
#define BNSCTRi(CR) BCCTRii( 4, ((CR)<<2)+3)
#define BUNCTRi(CR) BCCTRii(12, ((CR)<<2)+3)
#define BNUCTRi(CR) BCCTRii( 4, ((CR)<<2)+3)
#define BLTCTRLi(CR) BCCTRLii(12, ((CR)<<2)+0) /* [1, Table F-10] */
#define BLECTRLi(CR) BCCTRLii( 4, ((CR)<<2)+1)
#define BEQCTRLi(CR) BCCTRLii(12, ((CR)<<2)+2)
#define BGECTRLi(CR) BCCTRLii( 4, ((CR)<<2)+0)
#define BGTCTRLi(CR) BCCTRLii(12, ((CR)<<2)+1)
#define BNLCTRLi(CR) BCCTRLii( 4, ((CR)<<2)+0)
#define BNECTRLi(CR) BCCTRLii( 4, ((CR)<<2)+2)
#define BNGCTRLi(CR) BCCTRLii( 4, ((CR)<<2)+1)
#define BSOCTRLi(CR) BCCTRLii(12, ((CR)<<2)+3)
#define BNSCTRLi(CR) BCCTRLii( 4, ((CR)<<2)+3)
#define BUNCTRLi(CR) BCCTRLii(12, ((CR)<<2)+3)
#define BNUCTRLi(CR) BCCTRLii( 4, ((CR)<<2)+3)
#define BLTLR() BLTLRi(0) /* with implicit _cr0 */
#define BLELR() BLELRi(0)
#define BEQLR() BEQLRi(0)
#define BGELR() BGELRi(0)
#define BGTLR() BGTLRi(0)
#define BNLLR() BNLLRi(0)
#define BNELR() BNELRi(0)
#define BNGLR() BNGLRi(0)
#define BSOLR() BSOLRi(0)
#define BNSLR() BNSLRi(0)
#define BUNLR() BUNLRi(0)
#define BNULR() BNULRi(0)
#define BLTLRL() BLTLRLi(0)
#define BLELRL() BLELRLi(0)
#define BEQLRL() BEQLRLi(0)
#define BGELRL() BGELRLi(0)
#define BGTLRL() BGTLRLi(0)
#define BNLLRL() BNLLRLi(0)
#define BNELRL() BNELRLi(0)
#define BNGLRL() BNGLRLi(0)
#define BSOLRL() BSOLRLi(0)
#define BNSLRL() BNSLRLi(0)
#define BUNLRL() BUNLRLi(0)
#define BNULRL() BNULRLi(0)
#define BLTCTR() BLTCTRi(0)
#define BLECTR() BLECTRi(0)
#define BEQCTR() BEQCTRi(0)
#define BGECTR() BGECTRi(0)
#define BGTCTR() BGTCTRi(0)
#define BNLCTR() BNLCTRi(0)
#define BNECTR() BNECTRi(0)
#define BNGCTR() BNGCTRi(0)
#define BSOCTR() BSOCTRi(0)
#define BNSCTR() BNSCTRi(0)
#define BUNCTR() BUNCTRi(0)
#define BNUCTR() BNUCTRi(0)
#define BLTCTRL() BLTCTRLi(0)
#define BLECTRL() BLECTRLi(0)
#define BEQCTRL() BEQCTRLi(0)
#define BGECTRL() BGECTRLi(0)
#define BGTCTRL() BGTCTRLi(0)
#define BNLCTRL() BNLCTRLi(0)
#define BNECTRL() BNECTRLi(0)
#define BNGCTRL() BNGCTRLi(0)
#define BSOCTRL() BSOCTRLi(0)
#define BNSCTRL() BNSCTRLi(0)
#define BUNCTRL() BUNCTRLi(0)
#define BNUCTRL() BNUCTRLi(0)
#define BLTii(C,D) BC_EXT(12, ((C)<<2)+0, D) /* [1, Table F-11] */
#define BNLii(C,D) BC_EXT( 4, ((C)<<2)+0, D)
#define BGEii(C,D) BC_EXT( 4, ((C)<<2)+0, D)
#define BGTii(C,D) BC_EXT(12, ((C)<<2)+1, D)
#define BNGii(C,D) BC_EXT( 4, ((C)<<2)+1, D)
#define BLEii(C,D) BC_EXT( 4, ((C)<<2)+1, D)
#define BEQii(C,D) BC_EXT(12, ((C)<<2)+2, D)
#define BNEii(C,D) BC_EXT( 4, ((C)<<2)+2, D)
#define BSOii(C,D) BC_EXT(12, ((C)<<2)+3, D)
#define BNSii(C,D) BC_EXT( 4, ((C)<<2)+3, D)
#define BUNii(C,D) BC_EXT(12, ((C)<<2)+3, D)
#define BNUii(C,D) BC_EXT( 4, ((C)<<2)+3, D)
#define BLTi(D) BLTii(0,D) /* with implicit _cr0 */
#define BLEi(D) BLEii(0,D)
#define BEQi(D) BEQii(0,D)
#define BGEi(D) BGEii(0,D)
#define BGTi(D) BGTii(0,D)
#define BNLi(D) BNLii(0,D)
#define BNEi(D) BNEii(0,D)
#define BNGi(D) BNGii(0,D)
#define BSOi(D) BSOii(0,D)
#define BNSi(D) BNSii(0,D)
#define BUNi(D) BUNii(0,D)
#define BNUi(D) BNUii(0,D)
#define BLTLii(C,D) BCLiii(12, ((C)<<2)+0, D) /* [1, Table F-??] */
#define BLELii(C,D) BCLiii( 4, ((C)<<2)+1, D)
#define BEQLii(C,D) BCLiii(12, ((C)<<2)+2, D)
#define BGELii(C,D) BCLiii( 4, ((C)<<2)+0, D)
#define BGTLii(C,D) BCLiii(12, ((C)<<2)+1, D)
#define BNLLii(C,D) BCLiii( 4, ((C)<<2)+0, D)
#define BNELii(C,D) BCLiii( 4, ((C)<<2)+2, D)
#define BNGLii(C,D) BCLiii( 4, ((C)<<2)+1, D)
#define BSOLii(C,D) BCLiii(12, ((C)<<2)+3, D)
#define BNSLii(C,D) BCLiii( 4, ((C)<<2)+3, D)
#define BUNLii(C,D) BCLiii(12, ((C)<<2)+3, D)
#define BNULii(C,D) BCLiii( 4, ((C)<<2)+3, D)
#define BLTLi(D) BLTLii(0,D) /* with implicit _cr0 */
#define BLELi(D) BLELii(0,D)
#define BEQLi(D) BEQLii(0,D)
#define BGELi(D) BGELii(0,D)
#define BGTLi(D) BGTLii(0,D)
#define BNLLi(D) BNLLii(0,D)
#define BNELi(D) BNELii(0,D)
#define BNGLi(D) BNGLii(0,D)
#define BSOLi(D) BSOLii(0,D)
#define BNSLi(D) BNSLii(0,D)
#define BUNLi(D) BUNLii(0,D)
#define BNULi(D) BNULii(0,D)
/* Note: there are many tens of other simplified branches that are not (yet?) defined here */
#define CRSETi(BX) CREQViii(BX, BX, BX) /* [1, Table F-15] */
#define CRCLRi(BX) CRXORiii(BX, BX, BX)
#define CRMOVEii(BX,BY) CRORiii(BX, BY, BY)
#define CRNOTii(BX,BY) CRNORiii(BX, BY, BY)
#define MTLRr(RS) MTSPRir(8, RS) /* [1, Table F-20] */
#define MFLRr(RD) MFSPRri(RD, 8)
#define MTCTRr(RS) MTSPRir(9, RS)
#define MFCTRr(RD) MFSPRri(RD, 9)
#define MTXERr(RS) MTSPRir(1, RS)
#define MFXERr(RD) MFSPRri(RD, 1)
#define NOP() ORIrri(0, 0, 0) /* [1, Section F.9] */
#define LIri(RD,IM) ADDIrri(RD, 0, IM)
#define LISri(RD,IM) ADDISrri(RD, 0, IM)
#define LArm(RD,D,RA) ADDIrri(RD, RA, D)
#define LArrr(RD,RB,RA) ADDIrrr(RD, RA, RB)
#define MRrr(RA,RS) ORrrr(RA, RS, RS)
#define NOTrr(RA,RS) NORrrr(RA, RS, RS)
/* alternative parenthesised forms of extended indexed load/store insns */
#define LBZUrx(RD,RA,RB) LBZUXrrr(RD,RA,RB)
#define LBZrx(RD,RA,RB) LBZXrrr(RD,RA,RB)
#define LHAUrx(RD,RA,RB) LHAUXrrr(RD,RA,RB)
#define LHArx(RD,RA,RB) LHAXrrr(RD,RA,RB)
#define LHBRrx(RD,RA,RB) LHBRXrrr(RD,RA,RB)
#define LHZUrx(RD,RA,RB) LHZUXrrr(RD,RA,RB)
#define LHZrx(RD,RA,RB) LHZXrrr(RD,RA,RB)
#define LWBRrx(RD,RA,RB) LWBRXrrr(RD,RA,RB)
#define LWZUrx(RD, RA, RB) LWZUXrrr(RD, RA, RB)
#define LWZrx(RD, RA, RB) LWZXrrr(RD, RA, RB)
#define STBUrx(RD,RA,RB) STBUXrrr(RD,RA,RB)
#define STBrx(RD,RA,RB) STBXrrr(RD,RA,RB)
#define STHBRrx(RS,RA,RB) STHBRXrrr(RS,RA,RB)
#define STHUrx(RS,RA,RB) STHUXrrr(RS,RA,RB)
#define STHrx(RS,RA,RB) STHXrrr(RS,RA,RB)
#define STWBRrx(RS,RA,RB) STWBRXrrr(RS,RA,RB)
#define STWCrx(RS,RA,RB) STWCXrrr(RS,RA,RB)
#define STWCX_rx(RS,RA,RB) STWCX_rrr(RS,RA,RB)
#define STWUrx(RS,RA,RB) STWUXrrr(RS,RA,RB)
#define STWrx(RS,RA,RB) STWXrrr(RS,RA,RB)
#define LArx(RD,RB,RA) LArrr(RD,RB,RA)
#define _LO(I) (_jit_UL(I) & _MASK(16))
#define _HI(I) (_jit_UL(I) >> (16))
#define _A(OP,RD,RA,RB,RC,XO,RCx) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)|( _u5(RB)<<11)|_u5(RC)<<6|(_u5(XO)<<1)|_u1(RCx))
#define LFDrri(RD,RA,imm) _D(50,RD,RA,imm)
#define LFDUrri(RD,RA,imm) _D(51,RD,RA,imm)
#define LFDUxrrr(RD,RA,RB) _X(31,RD,RA,RB,631,0)
#define LFDxrrr(RD,RA,RB) _X(31,RD,RA,RB,599,0)
#define LFSrri(RD,RA,imm) _D(48,RD,RA,imm)
#define LFSUrri(RD,RA,imm) _D(49,RD,RA,imm)
#define LFSUxrrr(RD,RA,RB) _X(31,RD,RA,RB,567,0)
#define LFSxrrr(RD,RA,RB) _X(31,RD,RA,RB,535,0)
#define STFDrri(RS,RA,imm) _D(54,RS,RA,imm)
#define STFDUrri(RS,RA,imm) _D(55,RS,RA,imm)
#define STFDUxrrr(RS,RA,RB) _X(31,RS,RA,RB,759,0)
#define STFDxrrr(RS,RA,RB) _X(31,RS,RA,RB,727,0)
#define STFSrri(RS,RA,imm) _D(52,RS,RA,imm)
#define STFSUrri(RS,RA,imm) _D(53,RS,RA,imm)
#define STFSUxrrr(RS,RA,RB) _X(31,RS,RA,RB,695,0)
#define STFSxrrr(RS,RA,RB) _X(31,RS,RA,RB,663,0)
#define STFIWXrrr(RS,RA,RB) _X(31,RS,RA,RB,983,0)
#define FADDDrrr(RD,RA,RB) _A(63,RD,RA,RB,0,21,0)
#define FADDSrrr(RD,RA,RB) _A(59,RD,RA,RB,0,21,0)
#define FSUBDrrr(RD,RA,RB) _A(63,RD,RA,RB,0,20,0)
#define FSUBSrrr(RD,RA,RB) _A(59,RD,RA,RB,0,20,0)
#define FMULDrrr(RD,RA,RC) _A(63,RD,RA,0,RC,25,0)
#define FMULSrrr(RD,RA,RC) _A(59,RD,RA,0,RC,25,0)
#define FDIVDrrr(RD,RA,RB) _A(63,RD,RA,RB,0,18,0)
#define FDIVSrrr(RD,RA,RB) _A(59,RD,RA,RB,0,25,0)
#define FSQRTDrr(RD,RB) _A(63,RD,0,RB,0,22,0)
#define FSQRTSrr(RD,RB) _A(59,RD,0,RB,0,22,0)
#define FSELrrrr(RD,RA,RB,RC) _A(63,RD,RA,RB,RC,23,0)
#define FCTIWrr(RD,RB) _X(63,RD,0,RB,14,0)
#define FCTIWZrr(RD,RB) _X(63,RD,0,RB,15,0)
#define FRSPrr(RD,RB) _X(63,RD,0,RB,12,0)
#define FABSrr(RD,RB) _X(63,RD,0,RB,264,0)
#define FNABSrr(RD,RB) _X(63,RD,0,RB,136,0)
#define FNEGrr(RD,RB) _X(63,RD,0,RB,40,0)
#define FMOVErr(RD,RB) _X(63,RD,0,RB,72,0)
#define FCMPOrrr(CR,RA,RB) _X(63,_u3((CR)<<2),RA,RB,32,0)
#define FCMPUrrr(CR,RA,RB) _X(63,_u3((CR)<<2),RA,RB,0,0)
#define MTFSFIri(CR,IMM) _X(63,_u5((CR)<<2),0,_u5((IMM)<<1),134,0)
/*** References:
*
* [1] "PowerPC Microprocessor Family: The Programming Environments For 32-Bit Microprocessors", Motorola, 1997.
*/
#endif
#endif /* __ccg_asm_ppc_h */

View File

@@ -1,298 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer (PowerPC version)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_core_h
#define __lightning_core_h
struct jit_local_state {
int nextarg_puti; /* number of integer args */
int nextarg_putf; /* number of float args */
int nextarg_putd; /* number of double args */
int nextarg_geti; /* Next r20-r25 reg. to be read */
int nextarg_getd; /* The FP args are picked up from FPR1 -> FPR10 */
int nbArgs; /* Number of arguments for the prolog */
};
#define JIT_SP 1
#define JIT_RET 3
#define JIT_R_NUM 3
#define JIT_V_NUM 7
#define JIT_R(i) (9+(i))
#define JIT_V(i) (31-(i))
#define JIT_AUX JIT_V(JIT_V_NUM) /* for 32-bit operands & shift counts */
#define jit_pfx_start() (_jit.jitl.trampolines)
#define jit_pfx_end() (_jit.jitl.free)
/* If possible, use the `small' instruction (rd, rs, imm)
* else load imm into r26 and use the `big' instruction (rd, rs, r26)
*/
#define jit_chk_ims(imm, small, big) (_siP(16,(imm)) ? (small) : (MOVEIri(JIT_AUX, imm), (big)) )
#define jit_chk_imu(imm, small, big) (_uiP(16,(imm)) ? (small) : (MOVEIri(JIT_AUX, imm), (big)) )
#define jit_chk_imu15(imm, small, big) (_uiP(15,(imm)) ? (small) : (MOVEIri(JIT_AUX, imm), (big)) )
#define jit_big_ims(imm, big) (MOVEIri(JIT_AUX, imm), (big))
#define jit_big_imu(imm, big) (MOVEIri(JIT_AUX, imm), (big))
/* Helper macros for branches */
#define jit_s_brai(rs, is, jmp) (jit_chk_ims (is, CMPWIri(rs, is), CMPWrr(rs, JIT_AUX)), jmp, _jit.x.pc)
#define jit_s_brar(s1, s2, jmp) ( CMPWrr(s1, s2), jmp, _jit.x.pc)
#define jit_u_brai(rs, is, jmp) (jit_chk_imu (is, CMPLWIri(rs, is), CMPLWrr(rs, JIT_AUX)), jmp, _jit.x.pc)
#define jit_u_brar(s1, s2, jmp) ( CMPLWrr(s1, s2), jmp, _jit.x.pc)
/* Helper macros for boolean tests. */
#define jit_sbooli(d, rs, is, jmp) (jit_chk_ims (is, CMPWIri (rs, is), CMPWrr(rs, JIT_AUX)), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)))
#define jit_sboolr(d, s1, s2, jmp) ( CMPWrr (s1, s2), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)))
#define jit_sbooli2(d, rs, is, jmp) (jit_chk_ims (is, CMPWIri (rs, is), CMPWrr(rs, JIT_AUX)), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)), XORIrri((d), (d), 1))
#define jit_sboolr2(d, s1, s2, jmp) ( CMPWrr (s1, s2), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)), XORIrri((d), (d), 1))
#define jit_ubooli(d, rs, is, jmp) (jit_chk_imu (is, CMPLWIri(rs, is), CMPLWrr(rs, JIT_AUX)), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)))
#define jit_uboolr(d, s1, s2, jmp) ( CMPLWrr (s1, s2), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)))
#define jit_ubooli2(d, rs, is, jmp) (jit_chk_imu (is, CMPLWIri(rs, is), CMPLWrr(rs, JIT_AUX)), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)), XORIrri((d), (d), 1))
#define jit_uboolr2(d, s1, s2, jmp) ( CMPLWrr (s1, s2), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)), XORIrri((d), (d), 1))
/* modulus with immediate
* movei r26, imm
* mtlr r31
* divw r31, rs, r26 (or divwu)
* mullw r31, r31, r26
* sub rs, rs, r26
* mflr r31
*/
#define _jit_mod(div, rs, imm) (MOVEIri(JIT_AUX, (imm)), MTLRr(31), (div), \
MULLWrrr(31, 31, JIT_AUX), SUBrrr((rs), (rs), JIT_AUX), \
MFLRr(31))
/* Patch a movei instruction made of a LIS at lis_pc and an ORI at ori_pc. */
#define jit_patch_movei(lis_pc, ori_pc, dest) \
(*(lis_pc) &= ~_MASK(16), *(lis_pc) |= _HI(dest), \
*(ori_pc) &= ~_MASK(16), *(ori_pc) |= _LO(dest)) \
/* Patch a branch instruction */
#define jit_patch_branch(jump_pc,pv) \
(*(jump_pc) &= ~_MASK(16) | 3, \
*(jump_pc) |= (_jit_UL(pv) - _jit_UL(jump_pc)) & _MASK(16))
#define jit_patch_ucbranch(jump_pc,pv) \
(*(jump_pc) &= ~_MASK(26) | 3, \
(*(jump_pc) |= (_jit_UL((pv)) - _jit_UL(jump_pc)) & _MASK(26)))
#define _jit_b_encoding (18 << 26)
#define _jit_blr_encoding ((19 << 26) | (20 << 21) | (00 << 16) | (00 << 11) | (16 << 1))
#define _jit_is_ucbranch(a) (((*(a) & (63<<26)) == _jit_b_encoding))
#define jit_patch_at(jump_pc, value) ( \
((*(jump_pc - 1) & ~1) == _jit_blr_encoding) \
? jit_patch_movei(((jump_pc) - 4), ((jump_pc) - 3), (value)) \
: ( _jit_is_ucbranch((jump_pc) - 1) \
? jit_patch_ucbranch((jump_pc) - 1, (value)) \
: jit_patch_branch((jump_pc) - 1, (value))))
#define jit_patch_movi(movi_pc, val) \
jit_patch_movei((movi_pc) - 2, (movi_pc) - 1, (val))
#define jit_arg_c() (_jitl.nextarg_geti--)
#define jit_arg_i() (_jitl.nextarg_geti--)
#define jit_arg_l() (_jitl.nextarg_geti--)
#define jit_arg_p() (_jitl.nextarg_geti--)
#define jit_arg_s() (_jitl.nextarg_geti--)
#define jit_arg_uc() (_jitl.nextarg_geti--)
#define jit_arg_ui() (_jitl.nextarg_geti--)
#define jit_arg_ul() (_jitl.nextarg_geti--)
#define jit_arg_us() (_jitl.nextarg_geti--)
/* Check Mach-O-Runtime documentation: Must skip GPR(s) whenever "corresponding" FPR is used */
#define jit_arg_f() (_jitl.nextarg_geti-- ,_jitl.nextarg_getd++)
#define jit_arg_d() (_jitl.nextarg_geti-=2,_jitl.nextarg_getd++)
#define jit_addi_i(d, rs, is) jit_chk_ims((is), ADDICrri((d), (rs), (is)), ADDrrr((d), (rs), JIT_AUX))
#define jit_addr_i(d, s1, s2) ADDrrr((d), (s1), (s2))
#define jit_addci_i(d, rs, is) jit_chk_ims((is), ADDICrri((d), (rs), (is)), ADDCrrr((d), (rs), JIT_AUX))
#define jit_addcr_i(d, s1, s2) ADDCrrr((d), (s1), (s2))
#define jit_addxi_i(d, rs, is) (MOVEIri(JIT_AUX, (is)), ADDErrr((d), (rs), JIT_AUX))
#define jit_addxr_i(d, s1, s2) ADDErrr((d), (s1), (s2))
#define jit_andi_i(d, rs, is) jit_chk_imu((is), ANDI_rri((d), (rs), (is)), ANDrrr((d), (rs), JIT_AUX))
#define jit_andr_i(d, s1, s2) ANDrrr((d), (s1), (s2))
#define jit_bmsi_i(label, rs, is) (jit_chk_imu((is), ANDI_rri(JIT_AUX, (rs), (is)), AND_rrr(JIT_AUX, (rs), JIT_AUX)), BGTi((label)), _jit.x.pc)
#define jit_bmci_i(label, rs, is) (jit_chk_imu((is), ANDI_rri(JIT_AUX, (rs), (is)), AND_rrr(JIT_AUX, (rs), JIT_AUX)), BEQi((label)), _jit.x.pc)
#define jit_bmsr_i(label, s1, s2) ( AND_rrr(JIT_AUX, (s1), (s2)), BGTi((label)), _jit.x.pc)
#define jit_bmcr_i(label, s1, s2) ( AND_rrr(JIT_AUX, (s1), (s2)), BEQi((label)), _jit.x.pc)
#define jit_beqi_i(label, rs, is) jit_s_brai((rs), (is), BEQi((label)) )
#define jit_beqr_i(label, s1, s2) jit_s_brar((s1), (s2), BEQi((label)) )
#define jit_bgei_i(label, rs, is) jit_s_brai((rs), (is), BGEi((label)) )
#define jit_bgei_ui(label, rs, is) jit_u_brai((rs), (is), BGEi((label)) )
#define jit_bger_i(label, s1, s2) jit_s_brar((s1), (s2), BGEi((label)) )
#define jit_bger_ui(label, s1, s2) jit_u_brar((s1), (s2), BGEi((label)) )
#define jit_bgti_i(label, rs, is) jit_s_brai((rs), (is), BGTi((label)) )
#define jit_bgti_ui(label, rs, is) jit_u_brai((rs), (is), BGTi((label)) )
#define jit_bgtr_i(label, s1, s2) jit_s_brar((s1), (s2), BGTi((label)) )
#define jit_bgtr_ui(label, s1, s2) jit_u_brar((s1), (s2), BGTi((label)) )
#define jit_blei_i(label, rs, is) jit_s_brai((rs), (is), BLEi((label)) )
#define jit_blei_ui(label, rs, is) jit_u_brai((rs), (is), BLEi((label)) )
#define jit_bler_i(label, s1, s2) jit_s_brar((s1), (s2), BLEi((label)) )
#define jit_bler_ui(label, s1, s2) jit_u_brar((s1), (s2), BLEi((label)) )
#define jit_blti_i(label, rs, is) jit_s_brai((rs), (is), BLTi((label)) )
#define jit_blti_ui(label, rs, is) jit_u_brai((rs), (is), BLTi((label)) )
#define jit_bltr_i(label, s1, s2) jit_s_brar((s1), (s2), BLTi((label)) )
#define jit_bltr_ui(label, s1, s2) jit_u_brar((s1), (s2), BLTi((label)) )
#define jit_bnei_i(label, rs, is) jit_s_brai((rs), (is), BNEi((label)) )
#define jit_bner_i(label, s1, s2) jit_s_brar((s1), (s2), BNEi((label)) )
#define jit_boaddi_i(label, rs, is) (MOVEIri(JIT_AUX, (is)), ADDOrrr((rs), (rs), JIT_AUX), MCRXRi(0), BGTi((label)), _jit.x.pc) /* GT = bit 1 of XER = OV */
#define jit_bosubi_i(label, rs, is) (MOVEIri(JIT_AUX, (is)), SUBCOrrr((rs), (rs), JIT_AUX), MCRXRi(0), BGTi((label)), _jit.x.pc)
#define jit_boaddr_i(label, s1, s2) ( ADDOrrr((s1), (s1), (s2)), MCRXRi(0), BGTi((label)), _jit.x.pc)
#define jit_bosubr_i(label, s1, s2) ( SUBCOrrr((s1), (s1), (s2)), MCRXRi(0), BGTi((label)), _jit.x.pc)
#define jit_boaddi_ui(label, rs, is) (jit_chk_ims ((is), ADDICri((rs), (rs), is), ADDCrr((rs), JIT_AUX)), MCRXRi(0), BEQi((label)), _jit.x.pc) /* EQ = bit 2 of XER = CA */
#define jit_bosubi_ui(label, rs, is) (jit_chk_ims ((is), SUBICri((rs), (rs), is), SUBCrr((rs), JIT_AUX)), MCRXRi(0), BEQi((label)), _jit.x.pc)
#define jit_boaddr_ui(label, s1, s2) ( ADDCrr((s1), (s1), (s2)), MCRXRi(0), BEQi((label)), _jit.x.pc)
#define jit_bosubr_ui(label, s1, s2) ( SUBCrr((s1), (s1), (s2)), MCRXRi(0), BEQi((label)), _jit.x.pc)
#define jit_calli(label) (jit_movi_p(JIT_AUX, (label)), MTCTRr(JIT_AUX), BCTRL(), _jitl.nextarg_puti = _jitl.nextarg_putf = _jitl.nextarg_putd = 0, _jit.x.pc)
#define jit_callr(reg) (MTCTRr(reg), BCTRL())
#define jit_divi_i(d, rs, is) jit_big_ims((is), DIVWrrr ((d), (rs), JIT_AUX))
#define jit_divi_ui(d, rs, is) jit_big_imu((is), DIVWUrrr((d), (rs), JIT_AUX))
#define jit_divr_i(d, s1, s2) DIVWrrr ((d), (s1), (s2))
#define jit_divr_ui(d, s1, s2) DIVWUrrr((d), (s1), (s2))
#define jit_eqi_i(d, rs, is) (jit_chk_ims((is), SUBIrri(JIT_AUX, (rs), (is)), SUBrrr(JIT_AUX, (rs), JIT_AUX)), SUBFICrri((d), JIT_AUX, 0), ADDErrr((d), (d), JIT_AUX))
#define jit_eqr_i(d, s1, s2) (SUBrrr(JIT_AUX, (s1), (s2)), SUBFICrri((d), JIT_AUX, 0), ADDErrr((d), (d), JIT_AUX))
#define jit_extr_c_i(d, rs) EXTSBrr((d), (rs))
#define jit_extr_s_i(d, rs) EXTSHrr((d), (rs))
#define jit_gei_i(d, rs, is) jit_sbooli2((d), (rs), (is), _lt)
#define jit_gei_ui(d, rs, is) jit_ubooli2((d), (rs), (is), _lt)
#define jit_ger_i(d, s1, s2) jit_sboolr2((d), (s1), (s2), _lt)
#define jit_ger_ui(d, s1, s2) jit_uboolr2((d), (s1), (s2), _lt)
#define jit_gti_i(d, rs, is) jit_sbooli ((d), (rs), (is), _gt)
#define jit_gti_ui(d, rs, is) jit_ubooli ((d), (rs), (is), _gt)
#define jit_gtr_i(d, s1, s2) jit_sboolr ((d), (s1), (s2), _gt)
#define jit_gtr_ui(d, s1, s2) jit_uboolr ((d), (s1), (s2), _gt)
#define jit_hmuli_i(d, rs, is) jit_big_ims((is), MULHWrrr ((d), (rs), JIT_AUX))
#define jit_hmuli_ui(d, rs, is) jit_big_imu((is), MULHWUrrr((d), (rs), JIT_AUX))
#define jit_hmulr_i(d, s1, s2) MULHWrrr ((d), (s1), (s2))
#define jit_hmulr_ui(d, s1, s2) MULHWUrrr((d), (s1), (s2))
#define jit_jmpi(label) (B_EXT((label)), _jit.x.pc)
#define jit_jmpr(reg) (MTLRr(reg), BLR())
#define jit_ldxi_c(d, rs, is) (jit_ldxi_uc((d), (rs), (is)), jit_extr_c_i((d), (d)))
#define jit_ldxr_c(d, s1, s2) (jit_ldxr_uc((d), (s1), (s2)), jit_extr_c_i((d), (d)))
#define jit_ldxi_i(d, rs, is) jit_chk_ims((d), LWZrm((d), (is), (rs)), LWZrx((d), JIT_AUX, (rs)))
#define jit_ldxi_s(d, rs, is) jit_chk_ims((d), LHArm((d), (is), (rs)), LHArx((d), JIT_AUX, (rs)))
#define jit_ldxi_uc(d, rs, is) jit_chk_ims((d), LBZrm((d), (is), (rs)), LBZrx((d), JIT_AUX, (rs)))
#define jit_ldxi_us(d, rs, is) jit_chk_ims((d), LHZrm((d), (is), (rs)), LHZrx((d), JIT_AUX, (rs)))
#define jit_ldxr_i(d, s1, s2) LWZrx((d), (s1), (s2))
#define jit_ldxr_s(d, s1, s2) LHArx((d), (s1), (s2))
#define jit_ldxr_uc(d, s1, s2) LBZrx((d), (s1), (s2))
#define jit_ldxr_us(d, s1, s2) LHZrx((d), (s1), (s2))
#define jit_lei_i(d, rs, is) jit_sbooli2((d), (rs), (is), _gt )
#define jit_lei_ui(d, rs, is) jit_ubooli2((d), (rs), (is), _gt )
#define jit_ler_i(d, s1, s2) jit_sboolr2((d), (s1), (s2), _gt )
#define jit_ler_ui(d, s1, s2) jit_uboolr2((d), (s1), (s2), _gt )
#define jit_lshi_i(d, rs, is) SLWIrri((d), (rs), (is))
#define jit_lshr_i(d, s1, s2) (ANDI_rri(JIT_AUX, (s2), 31), SLWrrr ((d), (s1), JIT_AUX))
#define jit_lti_i(d, rs, is) jit_sbooli ((d), (rs), (is), _lt )
#define jit_lti_ui(d, rs, is) jit_ubooli ((d), (rs), (is), _lt )
#define jit_ltr_i(d, s1, s2) jit_sboolr ((d), (s1), (s2), _lt )
#define jit_ltr_ui(d, s1, s2) jit_uboolr ((d), (s1), (s2), _lt )
#define jit_modi_i(d, rs, is) _jit_mod(jit_divi_i (31, (rs), JIT_AUX), (rs), (is))
#define jit_modi_ui(d, rs, is) _jit_mod(jit_divi_ui(31, (rs), JIT_AUX), (rs), (is))
#define jit_modr_i(d, s1, s2) (DIVWrrr(JIT_AUX, (s1), (s2)), MULLWrrr(JIT_AUX, JIT_AUX, (s2)), SUBrrr((d), (s1), JIT_AUX))
#define jit_modr_ui(d, s1, s2) (DIVWUrrr(JIT_AUX, (s1), (s2)), MULLWrrr(JIT_AUX, JIT_AUX, (s2)), SUBrrr((d), (s1), JIT_AUX))
#define jit_movi_i(d, is) MOVEIri((d), (is))
#define jit_movi_p(d, is) (LISri((d), _HI((is))),ORIrri((d),(d),_LO((is))),_jit.x.pc)
#define jit_movr_i(d, rs) MRrr((d), (rs))
#define jit_muli_i(d, rs, is) jit_chk_ims ((is), MULLIrri((d), (rs), (is)), MULLWrrr((d), (rs), JIT_AUX))
#define jit_muli_ui(d, rs, is) jit_chk_imu15((is), MULLIrri((d), (rs), (is)), MULLWrrr((d), (rs), JIT_AUX))
#define jit_mulr_i(d, s1, s2) MULLWrrr((d), (s1), (s2))
#define jit_mulr_ui(d, s1, s2) MULLWrrr((d), (s1), (s2))
#define jit_nei_i(d, rs, is) (jit_chk_ims((is), SUBIrri(JIT_AUX, (rs), (is)), SUBrrr(JIT_AUX, (rs), JIT_AUX)), ADDICrri((d), JIT_AUX, -1), SUBFErrr((d), (d), JIT_AUX))
#define jit_ner_i(d, s1, s2) (SUBrrr(JIT_AUX, (s1), (s2)), ADDICrri((d), JIT_AUX, -1), SUBFErrr((d), (d), JIT_AUX))
#define jit_nop() NOP()
#define jit_ori_i(d, rs, is) jit_chk_imu((is), ORIrri((d), (rs), (is)), ORrrr((d), (rs), JIT_AUX))
#define jit_orr_i(d, s1, s2) ORrrr((d), (s1), (s2))
#define jit_popr_i(rs) (LWZrm((rs), 0, 1), ADDIrri(1, 1, 4))
#define jit_prepare_i(numi) (_jitl.nextarg_puti = numi)
#define jit_prepare_f(numf) (_jitl.nextarg_putf = numf)
#define jit_prepare_d(numd) (_jitl.nextarg_putd = numd)
#define jit_prolog(n) _jit_prolog(&_jit, (n))
#define jit_pushr_i(rs) STWUrm((rs), -4, 1)
#define jit_pusharg_i(rs) (--_jitl.nextarg_puti, MRrr((3 + _jitl.nextarg_putd * 2 + _jitl.nextarg_putf + _jitl.nextarg_puti), (rs)))
#define jit_ret() _jit_epilog(&_jit)
#define jit_retval_i(rd) MRrr((rd), 3)
#define jit_rsbi_i(d, rs, is) jit_chk_ims((is), SUBFICrri((d), (rs), (is)), SUBFCrrr((d), (rs), JIT_AUX))
#define jit_rshi_i(d, rs, is) SRAWIrri((d), (rs), (is))
#define jit_rshi_ui(d, rs, is) SRWIrri ((d), (rs), (is))
#define jit_rshr_i(d, s1, s2) (ANDI_rri(JIT_AUX, (s2), 31), SRAWrrr ((d), (s1), JIT_AUX))
#define jit_rshr_ui(d, s1, s2) (ANDI_rri(JIT_AUX, (s2), 31), SRWrrr ((d), (s1), JIT_AUX))
#define jit_stxi_c(id, rd, rs) jit_chk_ims((id), STBrm((rs), (id), (rd)), STBrx((rs), (rd), JIT_AUX))
#define jit_stxi_i(id, rd, rs) jit_chk_ims((id), STWrm((rs), (id), (rd)), STWrx((rs), (rd), JIT_AUX))
#define jit_stxi_s(id, rd, rs) jit_chk_ims((id), STHrm((rs), (id), (rd)), STHrx((rs), (rd), JIT_AUX))
#define jit_stxr_c(d1, d2, rs) STBrx((rs), (d1), (d2))
#define jit_stxr_i(d1, d2, rs) STWrx((rs), (d1), (d2))
#define jit_stxr_s(d1, d2, rs) STHrx((rs), (d1), (d2))
#define jit_subr_i(d, s1, s2) SUBrrr((d), (s1), (s2))
#define jit_subcr_i(d, s1, s2) SUBCrrr((d), (s1), (s2))
#define jit_subxi_i(d, rs, is) jit_big_ims((is), SUBErrr((d), (rs), JIT_AUX))
#define jit_subxr_i(d, s1, s2) SUBErrr((d), (s1), (s2))
#define jit_xori_i(d, rs, is) jit_chk_imu((is), XORIrri((d), (rs), (is)), XORrrr((d), (rs), JIT_AUX))
#define jit_xorr_i(d, s1, s2) XORrrr((d), (s1), (s2))
/* Cannot use JIT_RZERO because having 0 in a register field on the PowerPC
* does not mean `a register whose value is 0', but rather `no register at
* all' */
#define jit_negr_i(d, rs) jit_rsbi_i((d), (rs), 0)
#define jit_negr_l(d, rs) jit_rsbi_l((d), (rs), 0)
#define jit_ldr_c(rd, rs) jit_ldxr_c((rd), 0, (rs))
#define jit_str_c(rd, rs) jit_stxr_c(0, (rd), (rs))
#define jit_ldr_s(rd, rs) jit_ldxr_s((rd), 0, (rs))
#define jit_str_s(rd, rs) jit_stxr_s(0, (rd), (rs))
#define jit_ldr_i(rd, rs) jit_ldxr_i((rd), 0, (rs))
#define jit_str_i(rd, rs) jit_stxr_i(0, (rd), (rs))
#define jit_ldr_uc(rd, rs) jit_ldxr_uc((rd), 0, (rs))
#define jit_ldr_us(rd, rs) jit_ldxr_us((rd), 0, (rs))
/* e.g.
* 0x01234567 _HA << 16 = 0x01230000 _LA = 0x00004567 _HA << 16 + LA = 0x01234567
* 0x89abcdef _HA << 16 = 0x89ac0000 _LA = 0xffffcdef _HA << 16 + LA = 0x89abcdef
*/
#define _HA(addr) ((_jit_UL(addr) >> 16) + (_jit_US(_jit_UL(addr)) >> 15))
#define _LA(addr) (_jit_UL(addr) - (_HA(addr) << 16))
#define jit_ldi_c(rd, is) (LISri(JIT_AUX, _HA(is)), jit_ldxi_c((rd), JIT_AUX, _LA(is)))
#define jit_sti_c(id, rs) (LISri(JIT_AUX, _HA(id)), jit_stxi_c(_LA(id), JIT_AUX, (rs)))
#define jit_ldi_s(rd, is) (LISri(JIT_AUX, _HA(is)), jit_ldxi_s((rd), JIT_AUX, _LA(is)))
#define jit_sti_s(id, rs) (LISri(JIT_AUX, _HA(id)), jit_stxi_s(_LA(id), JIT_AUX, (rs)))
#define jit_ldi_i(rd, is) (LISri(JIT_AUX, _HA(is)), jit_ldxi_i((rd), JIT_AUX, _LA(is)))
#define jit_sti_i(id, rs) (LISri(JIT_AUX, _HA(id)), jit_stxi_i(_LA(id), JIT_AUX, (rs)))
#define jit_ldi_uc(rd, is) (LISri(JIT_AUX, _HA(is)), jit_ldxi_uc((rd), JIT_AUX, _LA(is)))
#define jit_ldi_us(rd, is) (LISri(JIT_AUX, _HA(is)), jit_ldxi_us((rd), JIT_AUX, _LA(is)))
#endif /* __lightning_core_h */

View File

@@ -1,211 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Run-time assembler & support macros for the Sparc math unit
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_asm_fp_h
#define __lightning_asm_fp_h
#define JIT_FPR_NUM 6
#define JIT_FPR(i) (8+(i))
#define JIT_FPFR 0
/* Make space for 1 or 2 words, store address in REG */
#define jit_data(REG, D1) (_FBA (18, 8, 0, 1), _jit_L(D1), MFLRr(REG))
#define jit_addr_d(rd,s1,s2) FADDDrrr((rd),(s1),(s2))
#define jit_subr_d(rd,s1,s2) FSUBDrrr((rd),(s1),(s2))
#define jit_mulr_d(rd,s1,s2) FMULDrrr((rd),(s1),(s2))
#define jit_divr_d(rd,s1,s2) FDIVDrrr((rd),(s1),(s2))
#define jit_addr_f(rd,s1,s2) FADDSrrr((rd),(s1),(s2))
#define jit_subr_f(rd,s1,s2) FSUBSrrr((rd),(s1),(s2))
#define jit_mulr_f(rd,s1,s2) FMULSrrr((rd),(s1),(s2))
#define jit_divr_f(rd,s1,s2) FDIVSrrr((rd),(s1),(s2))
#define jit_movr_d(rd,rs) ( (rd) == (rs) ? 0 : FMOVErr((rd),(rs)))
#define jit_movi_d(reg0,d) do { \
double _v = (d); \
_FBA (18, 12, 0, 1); \
memcpy(_jit.x.uc_pc, &_v, sizeof (double)); \
_jit.x.uc_pc += sizeof (double); \
MFLRr (JIT_AUX); \
jit_ldxi_d((reg0), JIT_AUX, 0); \
} while(0)
#define jit_movr_f(rd,rs) ( (rd) == (rs) ? 0 : FMOVErr((rd),(rs)))
#define jit_movi_f(reg0,f) do { \
float _v = (f); \
_FBA (18, 8, 0, 1); \
memcpy(_jit.x.uc_pc, &_v, sizeof (float)); \
_jit.x.uc_pc += sizeof (float); \
MFLRr (JIT_AUX); \
jit_ldxi_f((reg0), JIT_AUX, 0); \
} while(0)
#define jit_abs_d(rd,rs) FABSrr((rd),(rs))
#define jit_negr_d(rd,rs) FNEGrr((rd),(rs))
#define jit_sqrt_d(rd,rs) FSQRTDrr((rd),(rs))
#define jit_ldxi_f(reg0, rs, is) (_siP(16,(is)) ? LFSrri((reg0),(rs),(is)) : (MOVEIri(JIT_AUX,(is)),LFSxrrr((reg0),(rs),JIT_AUX)))
#define jit_ldxi_d(reg0, rs, is) (_siP(16,(is)) ? LFDrri((reg0),(rs),(is)) : (MOVEIri(JIT_AUX,(is)),LFDxrrr((reg0),(rs),JIT_AUX)))
#define jit_ldxr_f(reg0, s1, s2) LFSxrrr((reg0),(s1),(s2))
#define jit_ldxr_d(reg0, s1, s2) LFDxrrr((reg0),(s1),(s2))
#define jit_ldi_f(reg0, is) (_siP(16,(is)) ? LFSrri((reg0),0,(is)) : (MOVEIri(JIT_AUX,(is)),LFSrri((reg0),JIT_AUX,0)))
#define jit_ldi_d(reg0, is) (_siP(16,(is)) ? LFDrri((reg0),0,(is)) : (MOVEIri(JIT_AUX,(is)),LFDrri((reg0),JIT_AUX,0)))
#define jit_ldr_f(reg0, rs) LFSrri((reg0),(rs),0)
#define jit_ldr_d(reg0, rs) LFDrri((reg0),(rs),0)
#define jit_stxi_f(id, rd, reg0) (_siP(16,(id)) ? STFSrri((reg0),(rd),(id)) : (MOVEIri(JIT_AUX,(id)),STFSrri((reg0),(rd),JIT_AUX)))
#define jit_stxi_d(id, rd, reg0) (_siP(16,(id)) ? STFDrri((reg0),(rd),(id)) : (MOVEIri(JIT_AUX,(id)),STFDrri((reg0),(rd),JIT_AUX)))
#define jit_stxr_f(d1, d2, reg0) STFSxrrr((reg0),(d1),(d2))
#define jit_stxr_d(d1, d2, reg0) STFDxrrr((reg0),(d1),(d2))
#define jit_sti_f(id, reg0) (_siP(16,(id)) ? STFSrri((reg0),0,(id)) : (MOVEIri(JIT_AUX,(id)),STFSrri((reg0),JIT_AUX,0)))
#define jit_sti_d(id, reg0) (_siP(16,(id)) ? STFDrri((reg0),0,(id)) : (MOVEIri(JIT_AUX,(id)),STFDrri((reg0),JIT_AUX,0)))
#define jit_str_f(rd, reg0) STFSrri((reg0),(rd),0)
#define jit_str_d(rd, reg0) STFDrri((reg0),(rd),0)
#define jit_fpboolr(d, s1, s2, rcbit) ( \
FCMPOrrr(_cr0,(s1),(s2)), \
MFCRr((d)), \
EXTRWIrrii((d), (d), 1, (rcbit)))
#define jit_fpboolr_neg(d, s1, s2,rcbit) ( \
FCMPOrrr(_cr0,(s1),(s2)), \
MFCRr((d)), \
EXTRWIrrii((d), (d), 1, (rcbit)), \
XORIrri((d), (d), 1))
#define jit_fpboolur(d, s1, s2, rcbit) ( \
FCMPUrrr(_cr0,(s1),(s2)), \
MFCRr((d)), \
EXTRWIrrii((d), (d), 1, (rcbit)))
#define jit_fpboolur_neg(d, s1, s2,rcbit) ( \
FCMPUrrr(_cr0,(s1),(s2)), \
MFCRr((d)), \
EXTRWIrrii((d), (d), 1, (rcbit)), \
XORIrri((d), (d), 1))
#define jit_fpboolur_or(d, s1, s2, bit1, bit2) (\
FCMPUrrr(_cr0,(s1),(s2)), \
CRORiii((bit1), (bit1), (bit2)), \
MFCRr((d)), \
EXTRWIrrii((d), (d), 1, (bit1)))
#define jit_gtr_d(d, s1, s2) jit_fpboolr ((d),(s1),(s2),_gt)
#define jit_ger_d(d, s1, s2) jit_fpboolr_neg((d),(s1),(s2),_lt)
#define jit_ltr_d(d, s1, s2) jit_fpboolr ((d),(s1),(s2),_lt)
#define jit_ler_d(d, s1, s2) jit_fpboolr_neg((d),(s1),(s2),_gt)
#define jit_eqr_d(d, s1, s2) jit_fpboolr ((d),(s1),(s2),_eq)
#define jit_ner_d(d, s1, s2) jit_fpboolr_neg((d),(s1),(s2),_eq)
#define jit_unordr_d(d, s1, s2) jit_fpboolur ((d),(s1),(s2),_un)
#define jit_ordr_d(d, s1, s2) jit_fpboolur_neg((d),(s1),(s2),_un)
#define jit_unler_d(d, s1, s2) jit_fpboolur_neg ((d), (s1), (s2), _gt)
#define jit_unltr_d(d, s1, s2) jit_fpboolur_or ((d), (s1), (s2), _un, _lt)
#define jit_unger_d(d, s1, s2) jit_fpboolur_neg ((d), (s1), (s2), _lt)
#define jit_ungtr_d(d, s1, s2) jit_fpboolur_or ((d), (s1), (s2), _un, _gt)
#define jit_ltgtr_d(d, s1, s2) jit_fpboolur_or ((d), (s1), (s2), _gt, _lt)
#define jit_uneqr_d(d, s1, s2) jit_fpboolur_or ((d), (s1), (s2), _un, _eq)
#define jit_fpbr(d, s1, s2, rcbit) ( \
FCMPOrrr(_cr0,(s1),(s2)), \
BTii ((rcbit), (d)))
#define jit_fpbr_neg(d, s1, s2,rcbit) ( \
FCMPOrrr(_cr0,(s1),(s2)), \
BFii ((rcbit), (d)))
#define jit_fpbur(d, s1, s2, rcbit) ( \
FCMPUrrr(_cr0,(s1),(s2)), \
BTii ((rcbit), (d)))
#define jit_fpbur_neg(d, s1, s2,rcbit) ( \
FCMPUrrr(_cr0,(s1),(s2)), \
BFii ((rcbit), (d)))
#define jit_fpbur_or(d, s1, s2, bit1, bit2) ( \
FCMPUrrr(_cr0,(s1),(s2)), \
CRORiii((bit1), (bit1), (bit2)), \
BTii ((bit1), (d)))
#define jit_bgtr_d(d, s1, s2) jit_fpbr ((d),(s1),(s2),_gt)
#define jit_bger_d(d, s1, s2) jit_fpbr_neg((d),(s1),(s2),_lt)
#define jit_bltr_d(d, s1, s2) jit_fpbr ((d),(s1),(s2),_lt)
#define jit_bler_d(d, s1, s2) jit_fpbr_neg((d),(s1),(s2),_gt)
#define jit_beqr_d(d, s1, s2) jit_fpbr ((d),(s1),(s2),_eq)
#define jit_bner_d(d, s1, s2) jit_fpbr_neg((d),(s1),(s2),_eq)
#define jit_bunordr_d(d, s1, s2) jit_fpbur ((d),(s1),(s2),_un)
#define jit_bordr_d(d, s1, s2) jit_fpbur_neg((d),(s1),(s2),_un)
#define jit_bunler_d(d, s1, s2) jit_fpbur_neg ((d), (s1), (s2), _gt)
#define jit_bunltr_d(d, s1, s2) jit_fpbur_or ((d), (s1), (s2), _un, _lt)
#define jit_bunger_d(d, s1, s2) jit_fpbur_neg ((d), (s1), (s2), _lt)
#define jit_bungtr_d(d, s1, s2) jit_fpbur_or ((d), (s1), (s2), _un, _gt)
#define jit_bltgtr_d(d, s1, s2) jit_fpbur_or ((d), (s1), (s2), _gt, _lt)
#define jit_buneqr_d(d, s1, s2) jit_fpbur_or ((d), (s1), (s2), _un, _eq)
#define jit_getarg_f(rd, ofs) jit_movr_f((rd),(ofs))
#define jit_getarg_d(rd, ofs) jit_movr_d((rd),(ofs))
#define jit_pusharg_d(rs) (_jitl.nextarg_putd--,jit_movr_d((_jitl.nextarg_putf+_jitl.nextarg_putd+1), (rs)))
#define jit_pusharg_f(rs) (_jitl.nextarg_putf--,jit_movr_f((_jitl.nextarg_putf+_jitl.nextarg_putd+1), (rs)))
#define jit_retval_d(op1) jit_movr_d(1, (op1))
#define jit_retval_f(op1) jit_movr_f(1, (op1))
#define jit_floorr_d_i(rd,rs) (MTFSFIri(7,3), \
FCTIWrr(7,(rs)), \
MOVEIri(JIT_AUX,-4), \
STFIWXrrr(7,JIT_SP,JIT_AUX), \
LWZrm((rd),-4,JIT_SP))
#define jit_ceilr_d_i(rd,rs) (MTFSFIri(7,2), \
FCTIWrr(7,(rs)), \
MOVEIri(JIT_AUX,-4), \
STFIWXrrr(7,JIT_SP,JIT_AUX), \
LWZrm((rd),-4,JIT_SP))
#define jit_roundr_d_i(rd,rs) (MTFSFIri(7,0), \
FCTIWrr(7,(rs)), \
MOVEIri(JIT_AUX,-4), \
STFIWXrrr(7,JIT_SP,JIT_AUX), \
LWZrm((rd),-4,JIT_SP))
#define jit_truncr_d_i(rd,rs) (FCTIWZrr(7,(rs)), \
MOVEIri(JIT_AUX,-4), \
STFIWXrrr(7,JIT_SP,JIT_AUX), \
LWZrm((rd),-4,JIT_SP))
#endif /* __lightning_asm_h */

View File

@@ -1,164 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer inline functions (PowerPC)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_funcs_h
#define __lightning_funcs_h
#if !defined(__GNUC__) && !defined(__GNUG__)
#error Go get GNU C, I do not know how to flush the cache
#error with this compiler.
#else
static void
jit_flush_code(void *start, void *end)
{
#ifndef LIGHTNING_CROSS
register char *ddest, *idest;
static int cache_line_size;
if (cache_line_size == 0) {
char buffer[8192];
int i, probe;
/* Find out the size of a cache line by zeroing one */
memset(buffer, 0xFF, 8192);
__asm__ __volatile__ ("dcbz 0,%0" : : "r"(buffer + 4096));
/* Probe for the beginning of the cache line. */
for(i = 0, probe = 4096; probe; probe >>= 1)
if (buffer[i | probe] != 0x00)
i |= probe;
/* i is now just before the start of the cache line */
i++;
for(cache_line_size = 1; i + cache_line_size < 8192; cache_line_size <<= 1)
if (buffer[i + cache_line_size] != 0x00)
break;
}
start -= ((long) start) & (cache_line_size - 1);
end -= ((long) end) & (cache_line_size - 1);
/* Force data cache write-backs */
for (ddest = (char *) start; ddest <= (char *) end; ddest += cache_line_size) {
__asm__ __volatile__ ("dcbst 0,%0" : : "r"(ddest));
}
__asm__ __volatile__ ("sync" : : );
/* Now invalidate the instruction cache */
for (idest = (char *) start; idest <= (char *) end; idest += cache_line_size) {
__asm__ __volatile__ ("icbi 0,%0" : : "r"(idest));
}
__asm__ __volatile__ ("isync" : : );
#endif /* !LIGHTNING_CROSS */
}
#endif /* __GNUC__ || __GNUG__ */
#define _jit (*jit)
static void
_jit_epilog(jit_state *jit)
{
int n = _jitl.nbArgs;
int frame_size, ofs;
int first_saved_reg = JIT_AUX - n;
int num_saved_regs = 32 - first_saved_reg;
frame_size = 24 + 32 + num_saved_regs * 4; /* r24..r31 + args */
frame_size += 15; /* the stack must be quad-word */
frame_size &= ~15; /* aligned */
#ifdef _CALL_DARWIN
LWZrm(0, frame_size + 8, 1); /* lwz r0, x+8(r1) (ret.addr.) */
#else
LWZrm(0, frame_size + 4, 1); /* lwz r0, x+4(r1) (ret.addr.) */
#endif
MTLRr(0); /* mtspr LR, r0 */
ofs = frame_size - num_saved_regs * 4;
LMWrm(first_saved_reg, ofs, 1); /* lmw rI, ofs(r1) */
ADDIrri(1, 1, frame_size); /* addi r1, r1, x */
BLR(); /* blr */
}
/* Emit a prolog for a function.
Upon entrance to the trampoline:
- LR = address where the real code for the function lies
- R3-R8 = parameters
Upon finishing the trampoline:
- R0 = return address for the function
- R25-R20 = parameters (order is reversed, 1st argument is R25)
The +32 in frame_size computation is to accound for the parameter area of
a function frame.
On PPC the frame must have space to host the arguments of any callee.
However, as it currently stands, the argument to jit_trampoline (n) is
the number of arguments of the caller we generate. Therefore, the
callee can overwrite a part of the stack (saved register area when it
flushes its own parameter on the stack. The addition of a constant
offset = 32 is enough to hold eight 4 bytes arguments. This is less
than perfect but is a reasonable work around for now.
Better solution must be investigated. */
static void
_jit_prolog(jit_state *jit, int n)
{
int frame_size;
int ofs, i;
int first_saved_reg = JIT_AUX - n;
int num_saved_regs = 32 - first_saved_reg;
_jitl.nextarg_geti = JIT_AUX - 1;
_jitl.nextarg_getd = 1;
_jitl.nbArgs = n;
frame_size = 24 + 32 + num_saved_regs * 4; /* r27..r31 + args */
frame_size += 15; /* the stack must be quad-word */
frame_size &= ~15; /* aligned */
MFLRr(0);
STWUrm(1, -frame_size, 1); /* stwu r1, -x(r1) */
ofs = frame_size - num_saved_regs * 4;
STMWrm(first_saved_reg, ofs, 1); /* stmw rI, ofs(r1) */
#ifdef _CALL_DARWIN
STWrm(0, frame_size + 8, 1); /* stw r0, x+8(r1) */
#else
STWrm(0, frame_size + 4, 1); /* stw r0, x+4(r1) */
#endif
for (i = 0; i < n; i++)
MRrr(JIT_AUX-1-i, 3+i); /* save parameters below r24 */
}
#undef _jit
#endif /* __lightning_funcs_h */

View File

@@ -1,383 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Run-time assembler for the SPARC
*
***********************************************************************/
/***********************************************************************
*
* Copyright 1999, 2000, 2001, 2002 Ian Piumarta
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_asm_h
#define __lightning_asm_h
/* <imm> = [0-9]+ -> add i, one parameter (imm)
* <reg> = %<imm> -> add r, one parameter (imm or _Rr(imm) )
* %g<imm> -> add r, one parameter (imm or _Rg(imm) )
* %o<imm> -> add r, one parameter (imm+8 or _Ro(imm) )
* %l<imm> -> add r, one parameter (imm+16 or _Rl(imm) )
* %i<imm> -> add r, one parameter (imm+24 or _Ri(imm) )
* <mem> = <imm>(<reg>) -> add m, two parameters (reg,imm)
* <idx> = <reg>(<reg>) -> add x, two parameters (reg,reg)
*/
typedef unsigned int jit_insn;
#ifndef LIGHTNING_DEBUG
#define _d30(BD) ((_jit_UL(BD) - _jit_UL(_jit.x.pc))>>2)
#define _d22(BD) _ck_d(22, _d30(BD))
#define _HI(I) (_jit_UL(I) >> (10))
#define _LO(I) (_jit_UL(I) & _MASK(10))
/* register names */
#define _y 0
#define _psr 1
#define _Rr(N) ( 0+(N))
#define _Rg(N) ( 0+(N))
#define _Ro(N) ( 8+(N))
#define _Rl(N) (16+(N))
#define _Ri(N) (24+(N))
/* instruction formats -- Figure 5-1, page 44 in */
/* SPARC International, "The SPARC Architecture Manual, Version 8", Prentice-Hall, 1992. */
#define _0i(RD, OP2, IMM) _jit_I((0<<30)| (_u5(RD)<<25)|(_u3(OP2)<<22)| _u22(IMM))
#define _0( A, CC, OP2, DSP) _jit_I((0<<30)|(_u1(A)<<29)|(_u4(CC)<<25)|(_u3(OP2)<<22)| _d22(DSP))
#define _0d( A, CC, OP2, DSP) _jit_I((0<<30)|(_u1(A)<<29)|(_u4(CC)<<25)|(_u3(OP2)<<22)| _u22(DSP))
#define _1( DSP) _jit_I((1<<30)| _d30(DSP))
#define _2( RD, OP3, RS1, I, ASI, RS2) _jit_I((2<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)|(_u8(ASI)<<5)|_u5 (RS2))
#define _2i(RD, OP3, RS1, I, IMM) _jit_I((2<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)| _s13(IMM))
#define _2f(RD, OP3, RS1, OPF, RS2) _jit_I((2<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)| (_u9(OPF)<<5)|_u5 (RS2))
#define _3( RD, OP3, RS1, I, ASI, RS2) _jit_I((3<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)|(_u8(ASI)<<5)|_u5 (RS2))
#define _3i(RD, OP3, RS1, I, IMM) _jit_I((3<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)| _s13(IMM))
#define _FP1(RD, RS1, OPF, RS2) _2f((RD), 52, (RS1), (OPF), (RS2))
#define _FP2(RD, RS1, OPF, RS2) _2f((RD), 53, (RS1), (OPF), (RS2))
/* basic instructions [Section B, page 87] */
#define ADDrrr(RS1, RS2, RD) _2 ((RD), 0, (RS1), 0, 0, (RS2))
#define ADDrir(RS1, IMM, RD) _2i ((RD), 0, (RS1), 1, (IMM))
#define ADDCCrrr(RS1, RS2, RD) _2 ((RD), 16, (RS1), 0, 0, (RS2))
#define ADDCCrir(RS1, IMM, RD) _2i ((RD), 16, (RS1), 1, (IMM))
#define ADDXrrr(RS1, RS2, RD) _2 ((RD), 8, (RS1), 0, 0, (RS2))
#define ADDXrir(RS1, IMM, RD) _2i ((RD), 8, (RS1), 1, (IMM))
#define ADDXCCrrr(RS1, RS2, RD) _2 ((RD), 24, (RS1), 0, 0, (RS2))
#define ADDXCCrir(RS1, IMM, RD) _2i ((RD), 24, (RS1), 1, (IMM))
#define ANDrrr(RS1, RS2, RD) _2 ((RD), 1, (RS1), 0, 0, (RS2))
#define ANDrir(RS1, IMM, RD) _2i ((RD), 1, (RS1), 1, (IMM))
#define ANDCCrrr(RS1, RS2, RD) _2 ((RD), 17, (RS1), 0, 0, (RS2))
#define ANDCCrir(RS1, IMM, RD) _2i ((RD), 17, (RS1), 1, (IMM))
#define BNi(DISP) _0 (0, 0, 2, (DISP))
#define BN_Ai(DISP) _0 (1, 0, 2, (DISP))
#define BEi(DISP) _0 (0, 1, 2, (DISP))
#define BE_Ai(DISP) _0 (1, 1, 2, (DISP))
#define BLEi(DISP) _0 (0, 2, 2, (DISP))
#define BLE_Ai(DISP) _0 (1, 2, 2, (DISP))
#define BLi(DISP) _0 (0, 3, 2, (DISP))
#define BL_Ai(DISP) _0 (1, 3, 2, (DISP))
#define BLEUi(DISP) _0 (0, 4, 2, (DISP))
#define BLEU_Ai(DISP) _0 (1, 4, 2, (DISP))
#define BCSi(DISP) _0 (0, 5, 2, (DISP))
#define BCS_Ai(DISP) _0 (1, 5, 2, (DISP))
#define BNEGi(DISP) _0 (0, 6, 2, (DISP))
#define BNEG_Ai(DISP) _0 (1, 6, 2, (DISP))
#define BVSi(DISP) _0 (0, 7, 2, (DISP))
#define BVS_Ai(DISP) _0 (1, 7, 2, (DISP))
#define BAi(DISP) _0 (0, 8, 2, (DISP))
#define BA_Ai(DISP) _0 (1, 8, 2, (DISP))
#define BNEi(DISP) _0 (0, 9, 2, (DISP))
#define BNE_Ai(DISP) _0 (1, 9, 2, (DISP))
#define BGi(DISP) _0 (0, 10, 2, (DISP))
#define BG_Ai(DISP) _0 (1, 10, 2, (DISP))
#define BGEi(DISP) _0 (0, 11, 2, (DISP))
#define BGE_Ai(DISP) _0 (1, 11, 2, (DISP))
#define BGUi(DISP) _0 (0, 12, 2, (DISP))
#define BGU_Ai(DISP) _0 (1, 12, 2, (DISP))
#define BCCi(DISP) _0 (0, 13, 2, (DISP))
#define BCC_Ai(DISP) _0 (1, 13, 2, (DISP))
#define BPOSi(DISP) _0 (0, 14, 2, (DISP))
#define BPOS_Ai(DISP) _0 (1, 14, 2, (DISP))
#define BVCi(DISP) _0 (0, 15, 2, (DISP))
#define BVC_Ai(DISP) _0 (1, 15, 2, (DISP))
#define CALLi(DISP) _1 ((DISP))
#define FLUSHrr(RS1, RS2) _2 (0, 0x3b, (RS1), 0, 0, (RS2))
#define FLUSHir(IMM, RS1) _2i (0, 0x3b, (RS1), 1, (IMM))
#define JMPLxr(RS1, RS2, RD) _2 ((RD), 56, (RS1), 0, 0, (RS2))
#define JMPLmr(RS1, IMM, RD) _2i ((RD), 56, (RS1), 1, (IMM))
#define LDxr(RS1, RS2, RD) _3 ((RD), 0, (RS1), 0, 0, (RS2))
#define LDmr(RS1, IMM, RD) _3i ((RD), 0, (RS1), 1, (IMM))
#define LDUBxr(RS1, RS2, RD) _3 ((RD), 1, (RS1), 0, 0, (RS2))
#define LDUBmr(RS1, IMM, RD) _3i ((RD), 1, (RS1), 1, (IMM))
#define LDUHxr(RS1, RS2, RD) _3 ((RD), 2, (RS1), 0, 0, (RS2))
#define LDUHmr(RS1, IMM, RD) _3i ((RD), 2, (RS1), 1, (IMM))
#define LDDxr(RS1, RS2, RD) _3 ((RD), 3, (RS1), 0, 0, (RS2))
#define LDDmr(RS1, IMM, RD) _3i ((RD), 3, (RS1), 1, (IMM))
#define LDSBxr(RS1, RS2, RD) _3 ((RD), 9, (RS1), 0, 0, (RS2))
#define LDSBmr(RS1, IMM, RD) _3i ((RD), 9, (RS1), 1, (IMM))
#define LDSHxr(RS1, RS2, RD) _3 ((RD), 10, (RS1), 0, 0, (RS2))
#define LDSHmr(RS1, IMM, RD) _3i ((RD), 10, (RS1), 1, (IMM))
#define ORrrr(RS1, RS2, RD) _2 ((RD), 2, (RS1), 0, 0, (RS2))
#define ORrir(RS1, IMM, RD) _2i ((RD), 2, (RS1), 1, (IMM))
#define ORCCrrr(RS1, RS2, RD) _2 ((RD), 18, (RS1), 0, 0, (RS2))
#define ORCCrir(RS1, IMM, RD) _2i ((RD), 18, (RS1), 1, (IMM))
#define RDir(RS, RD) _2 ((RD), (RS)|0x28, 0, 0, 0,0)
#define RESTORErrr(RS1, RS2, RD) _2 ((RD), 61, (RS1), 0, 0, (RS2))
#define RESTORErir(RS1, IMM, RD) _2i ((RD), 61, (RS1), 1, (IMM))
#define SAVErrr(RS1, RS2, RD) _2 ((RD), 60, (RS1), 0, 0, (RS2))
#define SAVErir(RS1, IMM, RD) _2i ((RD), 60, (RS1), 1, (IMM))
#define SDIVrrr(RS1, RS2, RD) _2 ((RD), 15, (RS1), 0, 0, (RS2))
#define SDIVrir(RS1, IMM, RD) _2i ((RD), 15, (RS1), 1, (IMM))
#define SDIVCCrrr(RS1, RS2, RD) _2 ((RD), 31, (RS1), 0, 0, (RS2))
#define SDIVCCrir(RS1, IMM, RD) _2i ((RD), 31, (RS1), 1, (IMM))
#define SETHIir(IMM, RD) _0i ((RD), 4, (IMM))
#define SLLrrr(RS1, RS2, RD) _2 ((RD), 37, (RS1), 0, 0, (RS2))
#define SLLrir(RS1, IMM, RD) _2i ((RD), 37, (RS1), 1, (IMM))
#define SMULrrr(RS1, RS2, RD) _2 ((RD), 11, (RS1), 0, 0, (RS2))
#define SMULrir(RS1, IMM, RD) _2i ((RD), 11, (RS1), 1, (IMM))
#define SMULCCrrr(RS1, RS2, RD) _2 ((RD), 27, (RS1), 0, 0, (RS2))
#define SMULCCrir(RS1, IMM, RD) _2i ((RD), 27, (RS1), 1, (IMM))
#define SRArrr(RS1, RS2, RD) _2 ((RD), 39, (RS1), 0, 0, (RS2))
#define SRArir(RS1, IMM, RD) _2i ((RD), 39, (RS1), 1, (IMM))
#define SRLrrr(RS1, RS2, RD) _2 ((RD), 38, (RS1), 0, 0, (RS2))
#define SRLrir(RS1, IMM, RD) _2i ((RD), 38, (RS1), 1, (IMM))
#define STrx(RS, RD1, RD2) _3 ((RS), 4, (RD1), 0, 0, (RD2))
#define STrm(RS, RD, IMM) _3i ((RS), 4, (RD), 1, (IMM))
#define STBrx(RS, RD1, RD2) _3 ((RS), 5, (RD1), 0, 0, (RD2))
#define STBrm(RS, RD, IMM) _3i ((RS), 5, (RD), 1, (IMM))
#define STBAR() _0i (0, 0x28, 15, 0, 0)
#define STHrx(RS, RD1, RD2) _3 ((RS), 6, (RD1), 0, 0, (RD2))
#define STHrm(RS, RD, IMM) _3i ((RS), 6, (RD), 1, (IMM))
#define STDrx(RS, RD1, RD2) _3 ((RS), 7, (RD1), 0, 0, (RD2))
#define STDrm(RS, RD, IMM) _3i ((RS), 7, (RD), 1, (IMM))
#define SUBrrr(RS1, RS2, RD) _2 ((RD), 4, (RS1), 0, 0, (RS2))
#define SUBrir(RS1, IMM, RD) _2i ((RD), 4, (RS1), 1, (IMM))
#define SUBCCrrr(RS1, RS2, RD) _2 ((RD), 20, (RS1), 0, 0, (RS2))
#define SUBCCrir(RS1, IMM, RD) _2i ((RD), 20, (RS1), 1, (IMM))
#define SUBXrrr(RS1, RS2, RD) _2 ((RD), 12, (RS1), 0, 0, (RS2))
#define SUBXrir(RS1, IMM, RD) _2i ((RD), 12, (RS1), 1, (IMM))
#define SUBXCCrrr(RS1, RS2, RD) _2 ((RD), 28, (RS1), 0, 0, (RS2))
#define SUBXCCrir(RS1, IMM, RD) _2i ((RD), 28, (RS1), 1, (IMM))
#define UDIVrrr(RS1, RS2, RD) _2 ((RD), 14, (RS1), 0, 0, (RS2))
#define UDIVrir(RS1, IMM, RD) _2i ((RD), 14, (RS1), 1, (IMM))
#define UDIVCCrrr(RS1, RS2, RD) _2 ((RD), 30, (RS1), 0, 0, (RS2))
#define UDIVCCrir(RS1, IMM, RD) _2i ((RD), 30, (RS1), 1, (IMM))
#define UMULrrr(RS1, RS2, RD) _2 ((RD), 10, (RS1), 0, 0, (RS2))
#define UMULrir(RS1, IMM, RD) _2i ((RD), 10, (RS1), 1, (IMM))
#define UMULCCrrr(RS1, RS2, RD) _2 ((RD), 26, (RS1), 0, 0, (RS2))
#define UMULCCrir(RS1, IMM, RD) _2i ((RD), 26, (RS1), 1, (IMM))
#define WRrri(RS1, RS2, RD) _2 (0, (RD)|0x30, RS1, 0, 0, (RS2))
#define WRrii(RS1, IMM, RD) _2i (0, (RD)|0x30, RS1, 1, (IMM))
#define XORrrr(RS1, RS2, RD) _2 ((RD), 3, (RS1), 0, 0, (RS2))
#define XORrir(RS1, IMM, RD) _2i ((RD), 3, (RS1), 1, (IMM))
#define XORCCrrr(RS1, RS2, RD) _2 ((RD), 19, (RS1), 0, 0, (RS2))
#define XORCCrir(RS1, IMM, RD) _2i ((RD), 19, (RS1), 1, (IMM))
/* synonyms */
#define Bi(DISP) BAi((DISP))
#define B_Ai(DISP) BA_Ai((DISP))
#define BNZi(DISP) BNEi((DISP))
#define BNZ_Ai(DISP) BNE_Ai((DISP))
#define BZi(DISP) BEi((DISP))
#define BZ_Ai(DISP) BE_Ai((DISP))
#define BGEUi(DISP) BCCi((DISP))
#define BGEU_Ai(DISP) BCC_Ai((DISP))
#define BLUi(DISP) BCSi((DISP))
#define BLU_Ai(DISP) BCS_Ai((DISP))
#define LDUWxr(RS1, RS2, RD) LDxr((RS1), (RS2), (RD))
#define LDUWmr(RS1, IMM, RD) LDmr((RS1), (IMM), (RD))
#define LDSWxr(RS1, RS2, RD) LDxr((RS1), (RS2), (RD))
#define LDSWmr(RS1, IMM, RD) LDmr((RS1), (IMM), (RD))
#define STWrx(RS, RD1, RD2) STrx((RS), (RD1), (RD2))
#define STWrm(RS, RD, IMM) STrm((RS), (RD), (IMM))
/* synthetic instructions [Table A-1, page 85] */
#define BCLRrr(R,S) ANDNrrr((R), (S), (S))
#define BCLRir(I,R) ANDNrir((R), (I), (R))
#define BSETrr(R,S) ORrrr((R), (S), (S))
#define BSETir(I,R) ORrir((R), (I), (R))
#define BTOGrr(R,S) XORrrr((R), (S), (S))
#define BTOGir(I,R) XORrir((R), (I), (R))
#define BTSTrr(R,S) ANDCCrrr((R), (S), 0)
#define BTSTir(I,R) ANDCCrir((R), (I), 0)
#define CALLm(R,I) JMPLmr((R), (I), _Ro(7))
#define CALLx(R,S) JMPLxr((R), (S), _Ro(7))
#define CLRr(R) ORrrr(0, 0, (R))
#define CLRBm(R,I) STBrm(0, (R), (I))
#define CLRBx(R,S) STBrm(0, (R), (S))
#define CLRHm(R,I) STHrm(0, (R), (I))
#define CLRHx(R,S) STHrm(0, (R), (S))
#define CLRm(R,I) STrm(0, (R), (I))
#define CLRx(R,S) STrm(0, (R), (S))
#define CMPrr(RS1, RS2) SUBCCrrr((RS1), (RS2), 0)
#define CMPri(RS1, IMM) SUBCCrir((RS1), (IMM), 0)
#define DECr(R) SUBrir((R), 1, (R))
#define DECir(I,R) SUBrir((R), (I), (R))
#define DECCCr(R) SUBCCrir((R), 1, (R))
#define DECCCir(I,R) SUBCCrir((R), (I), (R))
#define INCr(R) ADDrir((R), 1, (R))
#define INCir(I,R) ADDrir((R), (I), (R))
#define INCCCr(R) ADDCCrir((R), 1, (R))
#define INCCCir(I,R) ADDCCrir((R), (I), (R))
#define JMPm(R,I) JMPLmr((R), (I), 0)
#define JMPx(R,S) JMPLxr((R), (S), 0)
#define MOVrr(R,S) ORrrr(0, (R), (S))
#define MOVir(I, R) ORrir(0, (I), (R))
#define NEGrr(R,S) SUBrrr(0, (R), (S))
#define NEGr(R) SUBrrr(0, (R), (R))
#define NOP() SETHIir(0, 0)
#define NOTrr(R,S) XNORrrr((R), 0, (S))
#define NOTr(R) XNORrrr((R), 0, (R))
#define RESTORE() RESTORErrr(0, 0, 0)
#define RET() JMPLmr(_Ri(7),8 ,0)
#define RETL() JMPLmr(_Ro(7),8 ,0)
#define SAVE() SAVErrr(0, 0, 0)
#define SETir(I,R) (_siP(13,(I)) ? MOVir((I),(R)) : SETir2(_HI(I), _LO(I), (R)))
#define SETir2(H,L,R) (SETHIir(H,R), (L ? ORrir(R,L,R) : 0))
/* BNZ,a executes the delay instruction if NZ (so skips if Z)
* BZ,a executes the delay instruction if Z (so skips if NZ). */
#define SKIPZ() _0d (1, 9, 2, 2) /* BNZ,a .+8 */
#define SKIPNZ() _0d (1, 1, 2, 2) /* BZ,a .+8 */
#define SKIP() _0d (1, 0, 2, 0) /* BN,a . */
#define TSTr(R) ORCCrrr(0, (R), 0)
#define WRii(IMM, RD) WRrii(0, (IMM), (RD))
#define WRri(RS2, RD) WRrri(0, (RS2), (RD))
#define LDFSRx(RS1, RS2) _3 (0, 33, (RS1), 0, 0, (RS2))
#define LDFSRm(RS1, IMM) _3i (0, 33, (RS1), 1, (IMM))
#define STFSRx(RD1, RD2) _3 (0, 37, (RD1), 0, 0, (RD2))
#define STFSRm(RD, IMM) _3i (0, 37, (RD), 1, (IMM))
#define FITODrr(FRS, FRD) _FP1((FRD), 0, 200, (FRS))
#define FITOSrr(FRS, FRD) _FP1((FRD), 0, 196, (FRS))
#define FDTOIrr(FRS, FRD) _FP1((FRD), 0, 210, (FRS))
#define FSTOIrr(FRS, FRD) _FP1((FRD), 0, 209, (FRS))
#define FSTODrr(FRS, FRD) _FP1((FRD), 0, 201, (FRS))
#define FDTOSrr(FRS, FRD) _FP1((FRD), 0, 198, (FRS))
#define FMOVSrr(FRS, FRD) _FP1((FRD), 0, 1, (FRS))
#define FNEGSrr(FRS, FRD) _FP1((FRD), 0, 5, (FRS))
#define FABSSrr(FRS, FRD) _FP1((FRD), 0, 9, (FRS))
#define FMOVDrr(FRS, FRD) _FP1((FRD), 0, 2, (FRS))
#define FNEGDrr(FRS, FRD) _FP1((FRD), 0, 6, (FRS))
#define FABSDrr(FRS, FRD) _FP1((FRD), 0, 10, (FRS))
#define FSQRTDrr(FRS, FRD) _FP1((FRD), 0, 42, (FRS))
#define FSQRTSrr(FRS, FRD) _FP1((FRD), 0, 41, (FRS))
#define FADDSrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 65, (FRS2))
#define FSUBSrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 69, (FRS2))
#define FMULSrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 73, (FRS2))
#define FDIVSrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 77, (FRS2))
#define FADDDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 66, (FRS2))
#define FSUBDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 70, (FRS2))
#define FMULDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 74, (FRS2))
#define FDIVDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 78, (FRS2))
#define FCMPSrr(FRS1, FRS2) _FP2(0, (FRS1), 81, (FRS2))
#define FCMPDrr(FRS1, FRS2) _FP2(0, (FRS1), 82, (FRS2))
#define LDFxr(RS1, RS2, RD) _3 ((RD), 32, (RS1), 0, 0, (RS2))
#define LDFmr(RS1, IMM, RD) _3i ((RD), 32, (RS1), 1, (IMM))
#define LDDFxr(RS1, RS2, RD) _3 ((RD), 35, (RS1), 0, 0, (RS2))
#define LDDFmr(RS1, IMM, RD) _3i ((RD), 35, (RS1), 1, (IMM))
#define STFrx(RS, RD1, RD2) _3 ((RS), 36, (RD1), 0, 0, (RD2))
#define STFrm(RS, RD1, IMM) _3i ((RS), 36, (RD1), 1, (IMM))
#define STDFrx(RS, RD1, RD2) _3 ((RS), 39, (RD1), 0, 0, (RD2))
#define STDFrm(RS, RD1, IMM) _3i ((RS), 39, (RD1), 1, (IMM))
#define FBNi(DISP) _0 (0, 0, 6, (DISP))
#define FBN_Ai(DISP) _0 (1, 0, 6, (DISP))
#define FBNEi(DISP) _0 (0, 1, 6, (DISP))
#define FBNE_Ai(DISP) _0 (1, 1, 6, (DISP))
#define FBLGi(DISP) _0 (0, 2, 6, (DISP))
#define FBLG_Ai(DISP) _0 (1, 2, 6, (DISP))
#define FBULi(DISP) _0 (0, 3, 6, (DISP))
#define FBUL_Ai(DISP) _0 (1, 3, 6, (DISP))
#define FBLi(DISP) _0 (0, 4, 6, (DISP))
#define FBL_Ai(DISP) _0 (1, 4, 6, (DISP))
#define FBUGi(DISP) _0 (0, 5, 6, (DISP))
#define FBUG_Ai(DISP) _0 (1, 5, 6, (DISP))
#define FBGi(DISP) _0 (0, 6, 6, (DISP))
#define FBG_Ai(DISP) _0 (1, 6, 6, (DISP))
#define FBUi(DISP) _0 (0, 7, 6, (DISP))
#define FBU_Ai(DISP) _0 (1, 7, 6, (DISP))
#define FBAi(DISP) _0 (0, 8, 6, (DISP))
#define FBA_Ai(DISP) _0 (1, 8, 6, (DISP))
#define FBEi(DISP) _0 (0, 9, 6, (DISP))
#define FBE_Ai(DISP) _0 (1, 9, 6, (DISP))
#define FBUEi(DISP) _0 (0, 10, 6, (DISP))
#define FBUE_Ai(DISP) _0 (1, 10, 6, (DISP))
#define FBGEi(DISP) _0 (0, 11, 6, (DISP))
#define FBGE_Ai(DISP) _0 (1, 11, 6, (DISP))
#define FBUGEi(DISP) _0 (0, 12, 6, (DISP))
#define FBUGE_Ai(DISP) _0 (1, 12, 6, (DISP))
#define FBLEi(DISP) _0 (0, 13, 6, (DISP))
#define FBLE_Ai(DISP) _0 (1, 13, 6, (DISP))
#define FBULEi(DISP) _0 (0, 14, 6, (DISP))
#define FBULE_Ai(DISP) _0 (1, 14, 6, (DISP))
#define FBOi(DISP) _0 (0, 15, 6, (DISP))
#define FBO_Ai(DISP) _0 (1, 15, 6, (DISP))
#endif
#endif /* __ccg_asm_sparc_h */

View File

@@ -1,265 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer (Sparc version)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_core_h
#define __lightning_core_h
#define JIT_R_NUM 3
#define JIT_V_NUM 6
#define JIT_R(i) ((i) ? _Rl((i) - 1) : _Rg(2))
#define JIT_V(i) _Rl((i)+2)
#define JIT_BIG _Rg(1) /* %g1 used to make 32-bit operands */
#define JIT_BIG2 _Ro(7) /* %o7 used to make 32-bit compare operands */
#define JIT_SP _Ro(6)
#define JIT_RZERO _Rg(0)
#define JIT_RET _Ri(0)
/* Delay slot scheduling: jmp generates branches with annulled delay
* slots; we toggle the annul bit if we can fill the slot. CALLs and
* cond. branches have a different meaning for the annul bit, so we
* automatically generate a NOP and eventually copy the delay insn onto
* it. Delay slots in RET are already used for RESTORE, so we don't
* schedule them.
*
* ,--- _jit.x.pc
* insn X X before
* cmp branch insn X X after (branch)
* `--- _jit.x.pc
* call insn insn X after (call)
* `--- _jit.x.pc
*/
struct jit_local_state {
int nextarg_put; /* Next %o reg. to be written */
int nextarg_get; /* Next %i reg. to be read */
jit_insn delay;
};
#define jit_fill_delay_after(branch) (_jitl.delay = *--_jit.x.pc, \
((branch) == _jit.x.pc /* check if NOP was inserted */ \
? (_jit.x.pc[-1] ^= 1<<29) /* no if branch, toggle annul bit */ \
: (_jit.x.pc[-1] = _jitl.delay)), /* yes if call, replace NOP with delay insn */ \
*_jit.x.pc = _jitl.delay, _jit.x.pc - 1) /* return addr of delay insn */
/* If possible, use the `small' instruction (rs, imm, rd)
* else load imm into %l6 and use the `big' instruction (rs, %l6, rd)
* jit_chk_imm2 uses %l7 instead of %l6 to avoid conflicts when using delay slots
*/
#define jit_chk_imm(imm, small, big) (_siP(13,(imm)) ? (small) : (SETir((imm), JIT_BIG), (big)) )
#define jit_chk_imm2(imm, small, big) (_siP(13,(imm)) ? (small) : (SETir((imm), JIT_BIG2), (big)) )
/* Helper macros for branches */
#define jit_branchi(rs, is, jmp, nop) (jit_chk_imm2(is, CMPri(rs, is), CMPrr(rs, JIT_BIG2)), jmp, nop, _jit.x.pc - 1)
#define jit_branchr(s1, s2, jmp, nop) ( CMPrr(s1, s2), jmp, nop, _jit.x.pc - 1)
/* Helper macros for boolean tests -- delay slot sets d to 1;
* taken branch leaves it to 1, not-taken branch resets it to 0 */
#define jit_booli(d, rs, is, jmp) (jit_chk_imm (is, CMPri(rs, is), CMPrr(rs, JIT_BIG)), jmp, MOVir(1, (d)), MOVir(0, (d)))
#define jit_boolr(d, s1, s2, jmp) ( CMPrr(s1, s2), jmp, MOVir(1, (d)), MOVir(0, (d)))
/* Helper macros for division
* The architecture specifies that there must be 3 instructions between *
* a y register write and a use of it for correct results. */
#define jit_prepare_y(rs, is) (SRArir(rs, 31, JIT_BIG), WRri(JIT_BIG, _y), NOP(), NOP(), NOP(), _jit.x.pc -= jit_immsize(is))
#define jit_clr_y(rs, is) ( WRri(0, _y), NOP(), NOP(), NOP(), _jit.x.pc -= jit_immsize(is))
#define jit_modr(jit_div, jit_mul, d, s1, s2) \
(jit_div (JIT_BIG, s1, s2), \
jit_mul (JIT_BIG, JIT_BIG, s2), \
jit_subr_i (d, s1, JIT_BIG))
#define jit_modi(jit_divi, jit_muli, jit_divr, jit_mulr, d, rs, is) \
(_siP(13,(imm)) \
? (jit_divi (JIT_BIG, rs, is), \
jit_muli (JIT_BIG, JIT_BIG, is), \
jit_subr_i (d, rs, JIT_BIG)) \
: (SETir ((is), JIT_BIG2), \
jit_modr (jit_divr, jit_mulr, d, rs, JIT_BIG2)))
/* How many instruction are needed to put imm in a register. */
#define jit_immsize(imm) (!(imm) ? 0 : \
(!_siP((imm), 13) && ((imm) & 0x3ff) ? 2 : 1))
/* branch instructions return the address of the *delay* instruction -- this
* is just a helper macro that makes jit_patch more readable.
*/
#define jit_patch_(jump_pc,pv) \
(*jump_pc &= ~_MASK(22), \
*jump_pc |= ((_jit_UL((pv)) - _jit_UL(jump_pc)) >> 2) & _MASK(22))
#define jit_patch_set(sethi_pc, or_pc, dest) \
(*(sethi_pc) &= ~_MASK(22), *(sethi_pc) |= _HI(dest), \
*(or_pc) &= ~_MASK(13), *(or_pc) |= _LO(dest)) \
#define jit_patch_movi(movi_pc, val) \
jit_patch_set((movi_pc) - 2, (movi_pc) - 1, (val))
#define jit_arg_c() (_jitl.nextarg_get++)
#define jit_arg_i() (_jitl.nextarg_get++)
#define jit_arg_l() (_jitl.nextarg_get++)
#define jit_arg_p() (_jitl.nextarg_get++)
#define jit_arg_s() (_jitl.nextarg_get++)
#define jit_arg_uc() (_jitl.nextarg_get++)
#define jit_arg_ui() (_jitl.nextarg_get++)
#define jit_arg_ul() (_jitl.nextarg_get++)
#define jit_arg_us() (_jitl.nextarg_get++)
#define jit_addi_i(d, rs, is) jit_chk_imm((is), ADDrir((rs), (is), (d)), ADDrrr((rs), JIT_BIG, (d)))
#define jit_addr_i(d, s1, s2) ADDrrr((s1), (s2), (d))
#define jit_addci_i(d, rs, is) jit_chk_imm((is), ADDCCrir((rs), (is), (d)), ADDCCrrr((rs), JIT_BIG, (d)))
#define jit_addcr_i(d, s1, s2) ADDCCrrr((s1), (s2), (d))
#define jit_addxi_i(d, rs, is) jit_chk_imm((is), ADDXCCrir((rs), (is), (d)), ADDXCCrrr((rs), JIT_BIG, (d)))
#define jit_addxr_i(d, s1, s2) ADDXCCrrr((s1), (s2), (d))
#define jit_andi_i(d, rs, is) jit_chk_imm((is), ANDrir((rs), (is), (d)), ANDrrr((rs), JIT_BIG, (d)))
#define jit_andr_i(d, s1, s2) ANDrrr((s1), (s2), (d))
#define jit_beqi_i(label, rs, is) jit_branchi((rs), (is), BEi((label)), NOP() )
#define jit_beqr_i(label, s1, s2) jit_branchr((s1), (s2), BEi((label)), NOP() )
#define jit_bgei_i(label, rs, is) jit_branchi((rs), (is), BGEi((label)), NOP() )
#define jit_bgei_ui(label, rs, is) jit_branchi((rs), (is), BGEUi((label)), NOP() )
#define jit_bger_i(label, s1, s2) jit_branchr((s1), (s2), BGEi((label)), NOP() )
#define jit_bger_ui(label, s1, s2) jit_branchr((s1), (s2), BGEUi((label)), NOP() )
#define jit_bgti_i(label, rs, is) jit_branchi((rs), (is), BGi((label)), NOP() )
#define jit_bgti_ui(label, rs, is) jit_branchi((rs), (is), BGUi((label)), NOP() )
#define jit_bgtr_i(label, s1, s2) jit_branchr((s1), (s2), BGi((label)), NOP() )
#define jit_bgtr_ui(label, s1, s2) jit_branchr((s1), (s2), BGUi((label)), NOP() )
#define jit_blei_i(label, rs, is) jit_branchi((rs), (is), BLEi((label)), NOP() )
#define jit_blei_ui(label, rs, is) jit_branchi((rs), (is), BLEUi((label)), NOP() )
#define jit_bler_i(label, s1, s2) jit_branchr((s1), (s2), BLEi((label)), NOP() )
#define jit_bler_ui(label, s1, s2) jit_branchr((s1), (s2), BLEUi((label)), NOP() )
#define jit_blti_i(label, rs, is) jit_branchi((rs), (is), BLi((label)), NOP() )
#define jit_blti_ui(label, rs, is) jit_branchi((rs), (is), BLUi((label)), NOP() )
#define jit_bltr_i(label, s1, s2) jit_branchr((s1), (s2), BLi((label)), NOP() )
#define jit_bltr_ui(label, s1, s2) jit_branchr((s1), (s2), BLUi((label)), NOP() )
#define jit_bnei_i(label, rs, is) jit_branchi((rs), (is), BNEi((label)), NOP() )
#define jit_bner_i(label, s1, s2) jit_branchr((s1), (s2), BNEi((label)), NOP() )
#define jit_bmsi_i(label, rs, is) (jit_chk_imm((is), BTSTir((is), (rs)), BTSTrr((rs), JIT_BIG)), BNEi((label)), NOP(), _jit.x.pc - 1)
#define jit_bmci_i(label, rs, is) (jit_chk_imm((is), BTSTir((is), (rs)), BTSTrr((rs), JIT_BIG)), BEi((label)), NOP(), _jit.x.pc - 1)
#define jit_bmsr_i(label, s1, s2) ( BTSTrr((s1), (s2)), BNEi((label)), NOP(), _jit.x.pc - 1)
#define jit_bmcr_i(label, s1, s2) ( BTSTrr((s1), (s2)), BEi((label)), NOP(), _jit.x.pc - 1)
#define jit_boaddi_i(label, rs, is) (jit_chk_imm((is), ADDCCrir((rs), (is), (rs)), ADDCCrrr((rs), JIT_BIG, (rs))), BVSi((label)), NOP(), _jit.x.pc - 1)
#define jit_bosubi_i(label, rs, is) (jit_chk_imm((is), SUBCCrir((rs), (is), (rs)), SUBCCrrr((rs), JIT_BIG, (rs))), BVSi((label)), NOP(), _jit.x.pc - 1)
#define jit_boaddr_i(label, s1, s2) ( ADDCCrrr((s1), (s2), (s1)), BVSi((label)), NOP(), _jit.x.pc - 1)
#define jit_bosubr_i(label, s1, s2) ( SUBCCrrr((s1), (s2), (s1)), BVSi((label)), NOP(), _jit.x.pc - 1)
#define jit_boaddi_ui(label, rs, is) (jit_chk_imm((is), ADDCCrir((rs), (is), (rs)), ADDCCrrr((rs), JIT_BIG, (rs))), BCSi((label)), NOP(), _jit.x.pc - 1)
#define jit_bosubi_ui(label, rs, is) (jit_chk_imm((is), SUBCCrir((rs), (is), (rs)), SUBCCrrr((rs), JIT_BIG, (rs))), BCSi((label)), NOP(), _jit.x.pc - 1)
#define jit_boaddr_ui(label, s1, s2) ( ADDCCrrr((s1), (s2), (s1)), BCSi((label)), NOP(), _jit.x.pc - 1)
#define jit_bosubr_ui(label, s1, s2) ( SUBCCrrr((s1), (s2), (s1)), BCSi((label)), NOP(), _jit.x.pc - 1)
#define jit_calli(label) (CALLi(label), NOP(), _jit.x.pc - 1)
#define jit_callr(reg) (CALLx((reg), 0), NOP())
#define jit_divi_i(d, rs, is) (jit_prepare_y((rs), 0x12345678), SETir((is), JIT_BIG), SDIVrrr((rs), JIT_BIG, (d)) )
#define jit_divi_ui(d, rs, is) (jit_clr_y((rs), 0x12345678), SETir((is), JIT_BIG), UDIVrrr((rs), JIT_BIG, (d)) )
#define jit_divr_i(d, s1, s2) (jit_prepare_y((s1), 0), SDIVrrr((s1), (s2), (d)))
#define jit_divr_ui(d, s1, s2) (jit_clr_y((s1), 0), UDIVrrr((s1), (s2), (d)))
#define jit_eqi_i(d, rs, is) jit_chk_imm((is), \
(SUBCCrir((rs), (is), (d)), ADDXCCrir((d), -1, JIT_BIG), SUBXrir(0,-1,(d))),\
jit_eqr_i(d, rs, JIT_BIG))
#define jit_eqr_i(d, s1, s2) (SUBCCrrr((s1), (s2), (d)), ADDXCCrir((d), -1, JIT_BIG), SUBXrir(0,-1,(d)))
#define jit_nei_i(d, rs, is) jit_chk_imm((is), \
(SUBCCrir((rs), (is), (d)), ADDXCCrir((d), -1, JIT_BIG), ADDXrrr(0,0,(d))),\
jit_ner_i(d, rs, JIT_BIG))
#define jit_ner_i(d, s1, s2) (SUBCCrrr((s1), (s2), (d)), ADDXCCrir((d), -1, JIT_BIG), ADDXrrr(0,0,(d)))
#define jit_gei_i(d, rs, is) jit_booli ((d), (rs), (is), BGEi(_jit.x.pc + 3) )
#define jit_gei_ui(d, rs, is) jit_booli ((d), (rs), (is), BGEUi(_jit.x.pc + 3))
#define jit_ger_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BGEi(_jit.x.pc + 3) )
#define jit_ger_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BGEUi(_jit.x.pc + 3))
#define jit_gti_i(d, rs, is) jit_booli ((d), (rs), (is), BGi(_jit.x.pc + 3) )
#define jit_gti_ui(d, rs, is) jit_booli ((d), (rs), (is), BGUi(_jit.x.pc + 3) )
#define jit_gtr_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BGi(_jit.x.pc + 3) )
#define jit_gtr_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BGUi(_jit.x.pc + 3) )
#define jit_hmuli_i(d, rs, is) (jit_muli_i (JIT_BIG, (rs), (is)), RDir (_y, (d)))
#define jit_hmuli_ui(d, rs, is) (jit_muli_ui(JIT_BIG, (rs), (is)), RDir (_y, (d)))
#define jit_hmulr_i(d, s1, s2) (jit_mulr_i (JIT_BIG, (s1), (s2)), RDir (_y, (d)))
#define jit_hmulr_ui(d, s1, s2) (jit_mulr_ui(JIT_BIG, (s1), (s2)), RDir (_y, (d)))
#define jit_jmpi(label) (BA_Ai((label)), _jit.x.pc)
#define jit_jmpr(reg) (JMPx(JIT_RZERO, (reg)), NOP(), _jit.x.pc - 1)
#define jit_ldxi_c(d, rs, is) jit_chk_imm((is), LDSBmr((rs), (is), (d)), LDSBxr((rs), JIT_BIG, (d)))
#define jit_ldxi_i(d, rs, is) jit_chk_imm((is), LDSWmr((rs), (is), (d)), LDSWxr((rs), JIT_BIG, (d)))
#define jit_ldxi_s(d, rs, is) jit_chk_imm((is), LDSHmr((rs), (is), (d)), LDSHxr((rs), JIT_BIG, (d)))
#define jit_ldxi_uc(d, rs, is) jit_chk_imm((is), LDUBmr((rs), (is), (d)), LDUBxr((rs), JIT_BIG, (d)))
#define jit_ldxi_us(d, rs, is) jit_chk_imm((is), LDUHmr((rs), (is), (d)), LDUHxr((rs), JIT_BIG, (d)))
#define jit_ldxr_c(d, s1, s2) LDSBxr((s1), (s2), (d))
#define jit_ldxr_i(d, s1, s2) LDSWxr((s1), (s2), (d))
#define jit_ldxr_s(d, s1, s2) LDSHxr((s1), (s2), (d))
#define jit_ldxr_uc(d, s1, s2) LDUBxr((s1), (s2), (d))
#define jit_ldxr_us(d, s1, s2) LDUHxr((s1), (s2), (d))
#define jit_lei_i(d, rs, is) jit_booli ((d), (rs), (is), BLEi(_jit.x.pc + 3) )
#define jit_lei_ui(d, rs, is) jit_booli ((d), (rs), (is), BLEUi(_jit.x.pc + 3))
#define jit_ler_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BLEi(_jit.x.pc + 3) )
#define jit_ler_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BLEUi(_jit.x.pc + 3))
#define jit_lshi_i(d, rs, is) SLLrir((rs), (is), (d))
#define jit_lshr_i(d, r1, r2) SLLrrr((r1), (r2), (d))
#define jit_lti_i(d, rs, is) jit_booli ((d), (rs), (is), BLi(_jit.x.pc + 3) )
#define jit_lti_ui(d, rs, is) jit_booli ((d), (rs), (is), BLUi(_jit.x.pc + 3) )
#define jit_ltr_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BLi(_jit.x.pc + 3) )
#define jit_ltr_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BLUi(_jit.x.pc + 3) )
#define jit_modi_i(d, rs, is) jit_modi(jit_divi_i, jit_muli_i, jit_divr_i, jit_mulr_i, (d), (rs), (is))
#define jit_modi_ui(d, rs, is) jit_modi(jit_divi_ui, jit_muli_ui, jit_divr_ui, jit_mulr_ui, (d), (rs), (is))
#define jit_modr_i(d, s1, s2) jit_modr(jit_divr_i, jit_mulr_i, (d), (s1), (s2))
#define jit_modr_ui(d, s1, s2) jit_modr(jit_divr_ui, jit_mulr_ui, (d), (s1), (s2))
#define jit_movi_i(d, is) SETir((is), (d))
#define jit_movi_p(d, is) (SETir2(_HI((is)), _LO((is)), (d)), _jit.x.pc)
#define jit_movr_i(d, rs) MOVrr((rs), (d))
#define jit_muli_i(d, rs, is) jit_chk_imm((is), SMULrir((rs), (is), (d)), SMULrrr((rs), JIT_BIG, (d)))
#define jit_muli_ui(d, rs, is) jit_chk_imm((is), UMULrir((rs), (is), (d)), UMULrrr((rs), JIT_BIG, (d)))
#define jit_mulr_i(d, s1, s2) SMULrrr((s1), (s2), (d))
#define jit_mulr_ui(d, s1, s2) UMULrrr((s1), (s2), (d))
#define jit_nop() NOP()
#define jit_ori_i(d, rs, is) jit_chk_imm((is), ORrir((rs), (is), (d)), ORrrr((rs), JIT_BIG, (d)))
#define jit_orr_i(d, s1, s2) ORrrr((s1), (s2), (d))
#define jit_patch_at(delay_pc, pv) jit_patch_ (((delay_pc) - 1) , (pv))
#define jit_popr_i(rs) (LDmr(JIT_SP, 0, (rs)), ADDrir(JIT_SP, 8, JIT_SP))
#define jit_prepare_i(num) (_jitl.nextarg_put += (num))
#define jit_prolog(numargs) (SAVErir(JIT_SP, -120, JIT_SP), _jitl.nextarg_get = _Ri(0))
#define jit_pushr_i(rs) (STrm((rs), JIT_SP, -8), SUBrir(JIT_SP, 8, JIT_SP))
#define jit_pusharg_i(rs) (--_jitl.nextarg_put, MOVrr((rs), _Ro(_jitl.nextarg_put)))
#define jit_ret() (RET(), RESTORE())
#define jit_retval_i(rd) MOVrr(_Ro(0), (rd))
#define jit_rshi_i(d, rs, is) SRArir((rs), (is), (d))
#define jit_rshi_ui(d, rs, is) SRLrir((rs), (is), (d))
#define jit_rshr_i(d, r1, r2) SRArrr((r1), (r2), (d))
#define jit_rshr_ui(d, r1, r2) SRLrrr((r1), (r2), (d))
#define jit_stxi_c(id, rd, rs) jit_chk_imm((id), STBrm((rs), (rd), (id)), STBrx((rs), (rd), JIT_BIG))
#define jit_stxi_i(id, rd, rs) jit_chk_imm((id), STWrm((rs), (rd), (id)), STWrx((rs), (rd), JIT_BIG))
#define jit_stxi_s(id, rd, rs) jit_chk_imm((id), STHrm((rs), (rd), (id)), STHrx((rs), (rd), JIT_BIG))
#define jit_stxr_c(d1, d2, rs) STBrx((rs), (d1), (d2))
#define jit_stxr_i(d1, d2, rs) STWrx((rs), (d1), (d2))
#define jit_stxr_s(d1, d2, rs) STHrx((rs), (d1), (d2))
#define jit_subr_i(d, s1, s2) SUBrrr((s1), (s2), (d))
#define jit_subcr_i(d, s1, s2) SUBCCrrr((s1), (s2), (d))
#define jit_subxi_i(d, rs, is) jit_chk_imm((is), SUBXCCrir((rs), (is), (d)), SUBXCCrrr((rs), JIT_BIG, (d)))
#define jit_subxr_i(d, s1, s2) SUBXCCrrr((s1), (s2), (d))
#define jit_xori_i(d, rs, is) jit_chk_imm((is), XORrir((rs), (is), (d)), XORrrr((rs), JIT_BIG, (d)))
#define jit_xorr_i(d, s1, s2) XORrrr((s1), (s2), (d))
#endif /* __lightning_core_h */

View File

@@ -1,222 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Run-time assembler & support macros for the PowerPC math unit
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_asm_fp_h
#define __lightning_asm_fp_h
#include <float.h>
#define JIT_FPR_NUM 6
#define JIT_FPR(i) (30-(i)*2)
#define JIT_FPTMP 18
#define jit_addr_f(rd,s1,s2) FADDSrrr((s1), (s2), (rd))
#define jit_subr_f(rd,s1,s2) FSUBSrrr((s1), (s2), (rd))
#define jit_mulr_f(rd,s1,s2) FMULSrrr((s1), (s2), (rd))
#define jit_divr_f(rd,s1,s2) FDIVSrrr((s1), (s2), (rd))
#define jit_addr_d(rd,s1,s2) FADDDrrr((s1), (s2), (rd))
#define jit_subr_d(rd,s1,s2) FSUBDrrr((s1), (s2), (rd))
#define jit_mulr_d(rd,s1,s2) FMULDrrr((s1), (s2), (rd))
#define jit_divr_d(rd,s1,s2) FDIVDrrr((s1), (s2), (rd))
#define jit_movr_f(rd,rs) FMOVSrr((rs), (rd))
#define jit_abs_d(rd,rs) FABSSrr((rs), (rd))
#define jit_negr_d(rd,rs) FNEGSrr((rs), (rd))
#define jit_sqrt_d(rd,rs) FSQRTSrr((rs), (rd))
#define jit_movr_d(rd,rs) FMOVDrr((rs), (rd))
#define jit_abs_f(rd,rs) FABSDrr((rs), (rd))
#define jit_negr_f(rd,rs) FNEGDrr((rs), (rd))
#define jit_sqrt_f(rd,rs) FSQRTDrr((rs), (rd))
#define jit_extr_f_d(rs, rd) FSTODrr((rs), (rd))
#define jit_extr_d_f(rs, rd) FDTOSrr((rs), (rd))
#define jit_movi_f(rd,immf) \
do { \
float _v = (immf); \
_1(_jit.x.pc + 3), LDFmr(_Ro(7), 8, (rd)); \
memcpy(_jit.x.uc_pc, &_v, sizeof (float)); \
_jit.x.uc_pc += sizeof (float); \
} while(0)
#define jit_movi_d(rd,immd) \
do { \
double _v = (immd); \
if ((long)_jit.x.pc & 4) NOP(); \
_1(_jit.x.pc + 4); \
LDDFmr(_Ro(7), 8, (rd)); \
memcpy(_jit.x.uc_pc, &_v, sizeof (double)); \
_jit.x.uc_pc += sizeof (double); \
} while(0)
#define jit_ldxi_f(rd, rs, is) jit_chk_imm((is), LDFmr((rs), (is), (rd)), LDFxr((rs), JIT_BIG, (rd)))
#define jit_ldxi_d(rd, rs, is) jit_chk_imm((is), LDDFmr((rs), (is), (rd)), LDDFxr((rs), JIT_BIG, (rd)))
#define jit_ldxr_f(rd, s1, s2) LDFxr((s1), (s2), (rd))
#define jit_ldxr_d(rd, s1, s2) LDDFxr((s1), (s2), (rd))
#define jit_stxi_f(id, rd, rs) jit_chk_imm((id), STFrm((rs), (rd), (id)), STFrx((rs), (rd), JIT_BIG))
#define jit_stxi_d(id, rd, rs) jit_chk_imm((id), STDFrm((rs), (rd), (id)), STDFrx((rs), (rd), JIT_BIG))
#define jit_stxr_f(d1, d2, rs) STFrx((rs), (d1), (d2))
#define jit_stxr_d(d1, d2, rs) STDFrx((rs), (d1), (d2))
#define jit_truncr_f_i(rd, rs) ( \
_1(_jit.x.pc + 3), \
FSTOIrr((rs), JIT_FPTMP), \
NOP(), \
STFrm(JIT_FPTMP, _Ro(7), 8), \
LDmr(_Ro(7), 8, (rd)))
#define jit_truncr_d_i(rd, rs) ( \
_1(_jit.x.pc + 3), \
FDTOIrr((rs), JIT_FPTMP), \
NOP(), \
STFrm(JIT_FPTMP, _Ro(7), 8), \
LDmr(_Ro(7), 8, (rd)))
#define jit_extr_i_d(rd, rs) (_1 (_jit.x.pc + 3), NOP(), NOP(), STrm((rs), _Ro(7), 8), LDFmr(_Ro(7), 8, (rd)), FITODrr((rd), (rd)))
#define jit_extr_i_f(rd, rs) (_1 (_jit.x.pc + 3), NOP(), NOP(), STrm((rs), _Ro(7), 8), LDFmr(_Ro(7), 8, (rd)), FITOSrr((rd), (rd)))
#define jit_do_round_f(rd, rs, fixup, mode) do { \
jit_movi_f (JIT_FPTMP, fixup); \
_1(_jit.x.pc + 4); \
SETHIir(_HI(mode << 29), JIT_BIG); \
NOP(); \
NOP(); \
STFSRm(_Ro(7), 8); /* store fsr */ \
LDmr(_Ro(7), 8, rd); \
XORrrr(rd, JIT_BIG, JIT_BIG); /* adjust mode */ \
STrm(JIT_BIG, _Ro(7), 12); \
LDFSRm(_Ro(7), 12); /* load fsr */ \
FADDSrrr ((rs), JIT_FPTMP, JIT_FPTMP); \
LDFSRm(_Ro(7), 8); \
FSTOIrr(JIT_FPTMP, JIT_FPTMP); \
STFrm(JIT_FPTMP, _Ro(7), 8); \
LDmr(_Ro(7), 8, (rd)); \
ADDCCrrr ((rd), (rd), 0); \
SUBXrrr ((rd), 0, (rd)); \
} while (0);
#define jit_do_round_d(rd, rs, fixup, mode) do { \
jit_movi_d (JIT_FPTMP, fixup); \
_1(_jit.x.pc + 4); \
SETHIir(_HI(mode << 29), JIT_BIG); \
NOP(); \
NOP(); \
STFSRm(_Ro(7), 8); /* store fsr */ \
LDmr(_Ro(7), 8, rd); \
XORrrr(rd, JIT_BIG, JIT_BIG); /* adjust mode */ \
STrm(JIT_BIG, _Ro(7), 12); \
LDFSRm(_Ro(7), 12); /* load fsr */ \
FADDDrrr ((rs), JIT_FPTMP, JIT_FPTMP); \
LDFSRm(_Ro(7), 8); \
FDTOIrr(JIT_FPTMP, JIT_FPTMP); \
STFrm(JIT_FPTMP, _Ro(7), 8); \
LDmr(_Ro(7), 8, (rd)); \
ADDCCrrr ((rd), (rd), 0); \
SUBXrrr ((rd), 0, (rd)); \
} while (0);
#define jit_roundr_f_i(rd, rs) do { \
jit_movi_f (JIT_FPTMP, 0.5); \
FADDSrrr ((rs), JIT_FPTMP, JIT_FPTMP); \
jit_truncr_f_i ((rd), JIT_FPTMP); \
ADDCCrrr ((rd), (rd), 0); \
SUBXrrr ((rd), 0, (rd)); \
} while (0)
#define jit_roundr_d_i(rd, rs) do { \
jit_movi_d (JIT_FPTMP, 0.5); \
FADDDrrr ((rs), JIT_FPTMP, JIT_FPTMP); \
jit_truncr_d_i ((rd), JIT_FPTMP); \
ADDCCrrr ((rd), (rd), 0); \
SUBXrrr ((rd), 0, (rd)); \
} while (0)
#define jit_ceilr_f_i(rd, rs) \
jit_do_round_f ((rd), (rs), 1.0f - FLT_EPSILON, 3)
#define jit_ceilr_d_i(rd, rs) \
jit_do_round_d ((rd), (rs), 1.0 - DBL_EPSILON, 3)
#define jit_floorr_f_i(rd, rs) \
jit_do_round_f ((rd), (rs), FLT_EPSILON, 2)
#define jit_floorr_d_i(rd, rs) \
jit_do_round_d ((rd), (rs), DBL_EPSILON, 2)
#define jit_ltr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBLi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ltr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBLi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ler_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBLEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ler_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBLEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_eqr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_eqr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ner_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBNEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ner_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBNEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ger_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBGEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ger_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBGEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_gtr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_gtr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unltr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBULi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unltr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBULi(_jit.x.pc + 3), MOVir (1, (d), MOVir (0, (d)))
#define jit_unler_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBULEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unler_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBULEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_uneqr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBUEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_uneqr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBUEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ltgtr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBLGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ltgtr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBLGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unger_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBUGEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unger_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBUGEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ungtr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBUGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ungtr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBUGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ordr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBOi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ordr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBOi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unordr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBUi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unordr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBUi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_prepare_f(num) (_jitl.nextarg_put += (num))
#define jit_prepare_d(num) (_jitl.nextarg_put += 2 * (num))
#define jit_arg_f() (_jitl.nextarg_get++)
#define jit_arg_d() (_jitl.nextarg_get += _jitl.nextarg_get & 1, _jitl.nextarg_get += 2, _jitl.nextarg_get - 2)
#define jit_getarg_f(rd, ofs) (STrm(ofs, _Ri(6), -24), LDFmr (_Ri(6), -24, (rd)))
#define jit_getarg_d(rd, ofs) (STDrm(ofs, _Ri(6), -24), LDDFmr (_Ri(6), -24, (rd)))
#define jit_pusharg_f(rs) (STFrm((rs), _Ri(6), -24), --_jitl.nextarg_put, LDmr (_Ri(6), -24, _Ro(_jitl.nextarg_put)))
#define jit_pusharg_d(rs) (STDFrm((rs), _Ri(6), -24), _jitl.nextarg_put -= 2, LDmr (_Ri(6), -24, _Ro(_jitl.nextarg_put)))
#define jit_retval_f(rs) jit_movr_f(0, rs)
#define jit_retval_d(rs) jit_movr_d(0, rs)
#endif /* __lightning_asm_fp_h */

View File

@@ -1,65 +0,0 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer inline functions (Sparc)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_funcs_h
#define __lightning_funcs_h
#if !defined(__GNUC__) && !defined(__GNUG__)
#error Go get GNU C, I do not know how to flush the cache
#error with this compiler.
#else
/* Why doesn't this compile?!?
* static void
* jit_flush_code(start, end)
* void *start;
* void *end;
*/
static void
jit_flush_code(void* start, void* end)
{
#ifndef LIGHTNING_CROSS
register char *dest;
__asm__ __volatile__ ("stbar");
for (dest = (char *)start; dest <= (char *)end; dest += 4) {
__asm__ __volatile__ ("flush %0"::"r"(dest));
}
/* [SPARC Architecture Manual v8, page 139, implementation note #5] */
__asm__ __volatile__ ("nop; nop; nop; nop; nop");
#endif
}
#endif
#endif /* __lightning_core_h */

File diff suppressed because it is too large Load Diff

View File

@@ -1,126 +0,0 @@
#ifndef PGF_LINEARIZER_H_
#define PGF_LINEARIZER_H_
#include <gu/enum.h>
/// Linearization of abstract syntax trees.
//
// PgfCncTree
//
/// A concrete syntax tree
typedef GuVariant PgfCncTree;
#ifdef PGF_DATA_H_
typedef enum {
PGF_CNC_TREE_APP,
PGF_CNC_TREE_CHUNKS,
PGF_CNC_TREE_LIT,
} PgfCncTreeTag;
typedef struct {
PgfCCat* ccat;
PgfCncFun* fun;
int fid;
size_t n_vars;
PgfPrintContext* context;
size_t n_args;
PgfCncTree args[];
} PgfCncTreeApp;
typedef struct {
PgfMetaId id;
size_t n_vars;
PgfPrintContext* context;
size_t n_args;
PgfCncTree args[];
} PgfCncTreeChunks;
typedef struct {
size_t n_vars;
PgfPrintContext* context;
int fid;
PgfLiteral lit;
} PgfCncTreeLit;
#endif
/// An enumeration of #PgfCncTree trees.
typedef GuEnum PgfCncTreeEnum;
/// Begin enumerating concrete syntax variants.
PGF_API_DECL PgfCncTreeEnum*
pgf_lzr_concretize(PgfConcr* concr, PgfExpr expr, GuExn* err, GuPool* pool);
typedef struct {
char nothing[0]; // Empty struct
} PgfLinNonExist;
PGF_API_DECL PgfCncTree
pgf_lzr_wrap_linref(PgfCncTree ctree, GuPool* pool);
typedef struct PgfLinFuncs PgfLinFuncs;
typedef enum {
PGF_CAPIT_NONE,
PGF_CAPIT_FIRST,
PGF_CAPIT_ALL,
PGF_CAPIT_NEXT
} PgfCapitState;
struct PgfLinFuncs
{
/// Output tokens
void (*symbol_token)(PgfLinFuncs** self, PgfToken tok);
/// Begin phrase
void (*begin_phrase)(PgfLinFuncs** self, PgfCId cat, int fid, GuString ann, PgfCId fun);
/// End phrase
void (*end_phrase)(PgfLinFuncs** self, PgfCId cat, int fid, GuString ann, PgfCId fun);
/// handling nonExist
void (*symbol_ne)(PgfLinFuncs** self);
/// token binding
void (*symbol_bind)(PgfLinFuncs** self);
/// capitalization
void (*symbol_capit)(PgfLinFuncs** self, PgfCapitState capit);
/// meta variable
void (*symbol_meta)(PgfLinFuncs** self, PgfMetaId id);
};
/// Linearize a concrete syntax tree.
PGF_API_DECL void
pgf_lzr_linearize(PgfConcr* concr, PgfCncTree ctree, size_t lin_idx,
PgfLinFuncs** funcs, GuPool* tmp_pool);
/// Linearize a concrete syntax tree as space-separated tokens.
PGF_API_DECL void
pgf_lzr_linearize_simple(PgfConcr* concr, PgfCncTree ctree, size_t lin_idx,
GuOut* out, GuExn* err,
GuPool* tmp_pool);
PGF_API_DECL void
pgf_lzr_get_table(PgfConcr* concr, PgfCncTree ctree,
size_t* n_lins, GuString** labels);
#ifdef PGF_DATA_H_
// Used internally in the parser
PGF_INTERNAL_DECL GuString
pgf_get_tokens(PgfSymbols* sym, uint16_t sym_idx, GuPool* pool);
#endif
#endif

View File

@@ -1,492 +0,0 @@
#include <gu/in.h>
#include <gu/utf8.h>
#include <pgf/literals.h>
#include <wctype.h>
static PgfExprProb*
pgf_match_string_lit(PgfLiteralCallback* self, PgfConcr* concr,
GuString ann,
GuString sentence, size_t* poffset,
GuPool *out_pool)
{
if (strcmp(ann,"s") != 0)
return NULL;
const uint8_t* buf = (uint8_t*) (sentence + *poffset);
const uint8_t* p = buf;
size_t len = 0;
while (*p && !gu_ucs_is_space(gu_utf8_decode(&p))) {
len = p - buf;
}
if (len > 0) {
PgfExprProb* ep = gu_new(PgfExprProb, out_pool);
ep->prob = 0;
PgfExprLit *expr_lit =
gu_new_variant(PGF_EXPR_LIT,
PgfExprLit,
&ep->expr, out_pool);
PgfLiteralStr *lit_str =
gu_new_flex_variant(PGF_LITERAL_STR,
PgfLiteralStr,
val, len+1,
&expr_lit->lit, out_pool);
memcpy(lit_str->val, buf, len);
lit_str->val[len] = 0;
*poffset += len;
return ep;
} else {
return NULL;
}
}
static void
pgf_predict_empty_next(GuEnum* self, void* to, GuPool* pool)
{
*((PgfTokenProb**) to) = NULL;
}
static GuEnum*
pgf_predict_empty(PgfLiteralCallback* self, PgfConcr* concr,
GuString ann,
GuString prefix,
GuPool *out_pool)
{
GuEnum* en = gu_new(GuEnum, out_pool);
en->next = pgf_predict_empty_next;
return en;
}
static PgfLiteralCallback pgf_string_literal_callback =
{ pgf_match_string_lit, pgf_predict_empty } ;
static PgfExprProb*
pgf_match_int_lit(PgfLiteralCallback* self, PgfConcr* concr,
GuString ann,
GuString sentence, size_t* poffset,
GuPool *out_pool)
{
if (strcmp(ann,"s") != 0)
return NULL;
const uint8_t* buf = (uint8_t*) (sentence + *poffset);
const uint8_t* p = buf;
size_t len = 0;
while (*p && !gu_ucs_is_space(gu_utf8_decode(&p))) {
len = p - buf;
}
if (len > 0) {
GuPool* tmp_pool = gu_local_pool();
PgfToken tok = gu_malloc(tmp_pool, len+1);
memcpy((char*) tok, buf, len);
((char*) tok)[len] = 0;
int val;
if (!gu_string_to_int(tok, &val)) {
gu_pool_free(tmp_pool);
return NULL;
}
gu_pool_free(tmp_pool);
PgfExprProb* ep = gu_new(PgfExprProb, out_pool);
ep->prob = 0;
PgfExprLit *expr_lit =
gu_new_variant(PGF_EXPR_LIT,
PgfExprLit,
&ep->expr, out_pool);
PgfLiteralInt *lit_int =
gu_new_variant(PGF_LITERAL_INT,
PgfLiteralInt,
&expr_lit->lit, out_pool);
lit_int->val = val;
*poffset += len;
return ep;
} else {
return NULL;
}
}
static PgfLiteralCallback pgf_int_literal_callback =
{ pgf_match_int_lit, pgf_predict_empty } ;
static PgfExprProb*
pgf_match_float_lit(PgfLiteralCallback* self, PgfConcr* concr,
GuString ann,
GuString sentence, size_t* poffset,
GuPool *out_pool)
{
if (strcmp(ann,"s") != 0)
return NULL;
const uint8_t* buf = (uint8_t*) (sentence + *poffset);
const uint8_t* p = buf;
size_t len = 0;
while (*p && !gu_ucs_is_space(gu_utf8_decode(&p))) {
len = p - buf;
}
if (len > 0) {
GuPool* tmp_pool = gu_local_pool();
PgfToken tok = gu_malloc(tmp_pool, len+1);
memcpy((char*) tok, buf, len);
((char*) tok)[len] = 0;
double val;
if (!gu_string_to_double(tok, &val)) {
gu_pool_free(tmp_pool);
return NULL;
}
gu_pool_free(tmp_pool);
PgfExprProb* ep = gu_new(PgfExprProb, out_pool);
ep->prob = 0;
PgfExprLit *expr_lit =
gu_new_variant(PGF_EXPR_LIT,
PgfExprLit,
&ep->expr, out_pool);
PgfLiteralFlt *lit_flt =
gu_new_variant(PGF_LITERAL_FLT,
PgfLiteralFlt,
&expr_lit->lit, out_pool);
lit_flt->val = val;
*poffset += len;
return ep;
} else {
return NULL;
}
}
static PgfLiteralCallback pgf_float_literal_callback =
{ pgf_match_float_lit, pgf_predict_empty } ;
typedef struct {
PgfMorphoCallback callback;
PgfAbstr* abstract;
PgfExpr expr;
bool is_known;
GuPool* out_pool;
} PgfMatchMorphoCallback;
static void
pgf_match_name_morpho_callback(PgfMorphoCallback* self_,
PgfCId lemma, GuString analysis, prob_t prob,
GuExn* err)
{
PgfMatchMorphoCallback* self =
gu_container(self_, PgfMatchMorphoCallback, callback);
PgfAbsFun* absfun =
gu_seq_binsearch(self->abstract->funs, pgf_absfun_order, PgfAbsFun, lemma);
if (absfun != NULL) {
if (strcmp(absfun->type->cid, "PN") == 0) {
self->expr = absfun->ep.expr;
} else if (strcmp(absfun->type->cid, "Weekday") == 0) {
PgfExprApp *expr_app =
gu_new_variant(PGF_EXPR_APP,
PgfExprApp,
&self->expr, self->out_pool);
GuString con = "weekdayPN";
PgfExprFun *expr_fun =
gu_new_flex_variant(PGF_EXPR_FUN,
PgfExprFun,
fun, strlen(con)+1,
&expr_app->fun, self->out_pool);
strcpy(expr_fun->fun, con);
expr_app->arg = absfun->ep.expr;
} else if (strcmp(absfun->type->cid, "Month") == 0) {
PgfExprApp *expr_app =
gu_new_variant(PGF_EXPR_APP,
PgfExprApp,
&self->expr, self->out_pool);
GuString con = "monthPN";
PgfExprFun *expr_fun =
gu_new_flex_variant(PGF_EXPR_FUN,
PgfExprFun,
fun, strlen(con)+1,
&expr_app->fun, self->out_pool);
strcpy(expr_fun->fun, con);
expr_app->arg = absfun->ep.expr;
} else {
self->is_known = true;
}
}
}
static PgfExprProb*
pgf_match_name_lit(PgfLiteralCallback* self, PgfConcr* concr,
GuString ann,
GuString sentence, size_t* poffset,
GuPool *out_pool)
{
if (strcmp(ann,"s") != 0)
return NULL;
GuPool* tmp_pool = gu_local_pool();
GuStringBuf *sbuf = gu_new_string_buf(tmp_pool);
GuOut* out = gu_string_buf_out(sbuf);
GuExn* err = gu_new_exn(tmp_pool);
const uint8_t* buf = (uint8_t*) (sentence + *poffset);
const uint8_t* p = buf;
int i = 0;
GuUCS ucs = gu_utf8_decode(&p);
while (gu_ucs_is_upper(ucs)) {
if (i > 0)
gu_putc(' ', out, err);
gu_out_utf8(ucs, out, err);
*poffset = p - ((uint8_t*) sentence);
ucs = gu_utf8_decode(&p);
while (ucs != 0 && !gu_ucs_is_space(ucs)) {
gu_out_utf8(ucs, out, err);
*poffset = p - ((uint8_t*) sentence);
ucs = gu_utf8_decode(&p);
}
i++;
while (gu_ucs_is_space(ucs))
ucs = gu_utf8_decode(&p);
}
PgfExprProb* ep = NULL;
if (i > 0) {
GuString name = gu_string_buf_freeze(sbuf, tmp_pool);
// Detect I and I'm in English
GuString concr_name = pgf_concrete_name(concr);
size_t concr_name_len = strlen(concr_name);
if (concr_name_len >= 3 && strcmp(concr_name+concr_name_len-3,"Eng") == 0) {
if (strcmp(name, "I") == 0 || strcmp(name, "I'm") == 0) {
gu_pool_free(tmp_pool);
return NULL;
}
}
PgfMatchMorphoCallback clo = { { pgf_match_name_morpho_callback },
concr->abstr,
gu_null_variant,
false,
out_pool
};
pgf_lookup_morpho(concr, name, &clo.callback, NULL);
if (clo.is_known) {
return NULL;
}
if (gu_variant_is_null(clo.expr)) {
PgfExprApp *expr_app1 =
gu_new_variant(PGF_EXPR_APP,
PgfExprApp,
&clo.expr, out_pool);
GuString con1 = "SymbPN";
PgfExprFun *expr_fun1 =
gu_new_flex_variant(PGF_EXPR_FUN,
PgfExprFun,
fun, strlen(con1)+1,
&expr_app1->fun, out_pool);
strcpy(expr_fun1->fun, con1);
PgfExprApp *expr_app2 =
gu_new_variant(PGF_EXPR_APP,
PgfExprApp,
&expr_app1->arg, out_pool);
GuString con2 = "MkSymb";
PgfExprFun *expr_fun2 =
gu_new_flex_variant(PGF_EXPR_FUN,
PgfExprFun,
fun, strlen(con2)+1,
&expr_app2->fun, out_pool);
strcpy(expr_fun2->fun, con2);
PgfExprLit *expr_lit =
gu_new_variant(PGF_EXPR_LIT,
PgfExprLit,
&expr_app2->arg, out_pool);
PgfLiteralStr *lit_str =
gu_new_flex_variant(PGF_LITERAL_STR,
PgfLiteralStr,
val, strlen(name)+1,
&expr_lit->lit, out_pool);
strcpy(lit_str->val, name);
}
ep = gu_new(PgfExprProb, out_pool);
ep->prob = 0;
ep->expr = clo.expr;
}
gu_pool_free(tmp_pool);
return ep;
}
PGF_API PgfLiteralCallback pgf_nerc_literal_callback =
{ pgf_match_name_lit, pgf_predict_empty } ;
static void
pgf_match_unknown_morpho_callback(PgfMorphoCallback* self_,
PgfCId lemma, GuString analysis, prob_t prob,
GuExn* err)
{
PgfMatchMorphoCallback* self =
gu_container(self_, PgfMatchMorphoCallback, callback);
self->is_known = true;
}
static PgfExprProb*
pgf_match_unknown_lit(PgfLiteralCallback* self, PgfConcr* concr,
GuString ann,
GuString sentence, size_t* poffset,
GuPool *out_pool)
{
const uint8_t* buf = (uint8_t*) (sentence + *poffset);
const uint8_t* p = buf;
PgfExprProb* ep = NULL;
GuUCS ucs = gu_utf8_decode(&p);
if (!gu_ucs_is_upper(ucs)) {
GuPool* tmp_pool = gu_local_pool();
GuStringBuf *sbuf = gu_new_string_buf(tmp_pool);
GuOut* out = gu_string_buf_out(sbuf);
GuExn* err = gu_new_exn(tmp_pool);
gu_out_utf8(ucs, out, err);
*poffset = p - ((uint8_t*) sentence);
ucs = gu_utf8_decode(&p);
while (ucs != 0 && !gu_ucs_is_space(ucs)) {
gu_out_utf8(ucs, out, err);
*poffset = p - ((uint8_t*) sentence);
ucs = gu_utf8_decode(&p);
}
GuString word = gu_string_buf_freeze(sbuf, tmp_pool);
PgfMatchMorphoCallback clo = { { pgf_match_unknown_morpho_callback },
concr->abstr,
gu_null_variant,
false,
out_pool
};
pgf_lookup_morpho(concr, word, &clo.callback, NULL);
if (!clo.is_known) {
ep = gu_new(PgfExprProb, out_pool);
ep->prob = 0;
PgfExprApp *expr_app =
gu_new_variant(PGF_EXPR_APP,
PgfExprApp,
&ep->expr, out_pool);
GuString con = "MkSymb";
PgfExprFun *expr_fun =
gu_new_flex_variant(PGF_EXPR_FUN,
PgfExprFun,
fun, strlen(con)+1,
&expr_app->fun, out_pool);
strcpy(expr_fun->fun, con);
PgfExprLit *expr_lit =
gu_new_variant(PGF_EXPR_LIT,
PgfExprLit,
&expr_app->arg, out_pool);
PgfLiteralStr *lit_str =
gu_new_flex_variant(PGF_LITERAL_STR,
PgfLiteralStr,
val, strlen(word)+1,
&expr_lit->lit, out_pool);
strcpy(lit_str->val, word);
}
gu_pool_free(tmp_pool);
}
return ep;
}
PGF_API PgfLiteralCallback pgf_unknown_literal_callback =
{ pgf_match_unknown_lit, pgf_predict_empty } ;
PgfCallbacksMap*
pgf_new_callbacks_map(PgfConcr* concr, GuPool *pool)
{
int fid;
PgfCCat* ccat;
PgfCallbacksMap* callbacks =
gu_new_addr_map(PgfCncCat*, PgfLiteralCallback*, &gu_null_struct, pool);
fid = -1;
ccat = gu_map_get(concr->ccats, &fid, PgfCCat*);
if (ccat != NULL)
gu_map_put(callbacks, ccat->cnccat,
PgfLiteralCallback*, &pgf_string_literal_callback);
fid = -2;
ccat = gu_map_get(concr->ccats, &fid, PgfCCat*);
if (ccat != NULL)
gu_map_put(callbacks, ccat->cnccat,
PgfLiteralCallback*, &pgf_int_literal_callback);
fid = -3;
ccat = gu_map_get(concr->ccats, &fid, PgfCCat*);
if (ccat != NULL)
gu_map_put(callbacks, ccat->cnccat,
PgfLiteralCallback*, &pgf_float_literal_callback);
return callbacks;
}
void
pgf_callbacks_map_add_literal(PgfConcr* concr, PgfCallbacksMap* callbacks,
PgfCId cat, PgfLiteralCallback* callback)
{
PgfCncCat* cnccat =
gu_map_get(concr->cnccats, cat, PgfCncCat*);
if (cnccat == NULL)
return;
gu_map_put(callbacks, cnccat,
PgfLiteralCallback*, callback);
}
PGF_INTERNAL PgfCCat*
pgf_literal_cat(PgfConcr* concr, PgfLiteral lit)
{
int fid;
switch (gu_variant_tag(lit)) {
case PGF_LITERAL_STR:
fid = -1;
break;
case PGF_LITERAL_INT:
fid = -2;
break;
case PGF_LITERAL_FLT:
fid = -3;
break;
default:
gu_impossible();
return NULL;
}
return gu_map_get(concr->ccats, &fid, PgfCCat*);
}

View File

@@ -1,15 +0,0 @@
#ifndef PGF_LITERALS_H_
#define PGF_LITERALS_H_
#include <pgf/data.h>
// literal for named entities recognition
PGF_API_DECL extern PgfLiteralCallback pgf_nerc_literal_callback;
// literal for finding unknown words
PGF_API_DECL extern PgfLiteralCallback pgf_unknown_literal_callback;
PGF_INTERNAL_DECL PgfCCat*
pgf_literal_cat(PgfConcr* concr, PgfLiteral lit);
#endif // PGF_LITERALS_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,220 +0,0 @@
#include <pgf/pgf.h>
#include <pgf/data.h>
#include <pgf/linearizer.h>
#include <gu/enum.h>
typedef struct {
int start, end;
PgfCId cat;
GuString ann;
} PgfPhrase;
typedef struct {
PgfLinFuncs* funcs;
bool bind;
GuOut* out;
GuExn* err;
int pos;
GuBuf* marks;
GuBuf* phrases;
int found, matches;
GuPool* pool;
} PgfMetricsLznState;
static void
pgf_metrics_put_space(PgfMetricsLznState* state)
{
if (state->bind)
state->bind = false;
else {
if (state->out != NULL)
gu_putc(' ', state->out, state->err);
state->pos++;
}
}
static void
pgf_metrics_lzn_symbol_token(PgfLinFuncs** funcs, PgfToken tok)
{
PgfMetricsLznState* state = gu_container(funcs, PgfMetricsLznState, funcs);
pgf_metrics_put_space(state);
if (state->out != NULL)
gu_string_write(tok, state->out, state->err);
state->pos += strlen(tok);
}
static void
pgf_metrics_lzn_begin_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString ann, PgfCId fun)
{
PgfMetricsLznState* state = gu_container(funcs, PgfMetricsLznState, funcs);
gu_buf_push(state->marks, int, state->pos);
}
static void
pgf_metrics_lzn_end_phrase1(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString ann, PgfCId fun)
{
PgfMetricsLznState* state = gu_container(funcs, PgfMetricsLznState, funcs);
int start = gu_buf_pop(state->marks, int);
int end = state->pos;
if (start != end) {
PgfPhrase* phrase = gu_new(PgfPhrase, state->pool);
phrase->start = start;
phrase->end = end;
phrase->cat = cat;
phrase->ann = ann;
gu_buf_push(state->phrases, PgfPhrase*, phrase);
}
}
static void
pgf_metrics_symbol_ne(PgfLinFuncs** funcs)
{
PgfMetricsLznState* state = gu_container(funcs, PgfMetricsLznState, funcs);
gu_raise(state->err, PgfLinNonExist);
}
static void
pgf_metrics_symbol_bind(PgfLinFuncs** funcs)
{
PgfMetricsLznState* state = gu_container(funcs, PgfMetricsLznState, funcs);
state->bind = true;
}
static void
pgf_metrics_lzn_end_phrase2(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString ann, PgfCId fun)
{
PgfMetricsLznState* state = gu_container(funcs, PgfMetricsLznState, funcs);
int start = gu_buf_pop(state->marks, int);
int end = state->pos;
if (start != end) {
size_t n_phrases = gu_buf_length(state->phrases);
for (size_t i = 0; i < n_phrases; i++) {
PgfPhrase* phrase = gu_buf_get(state->phrases, PgfPhrase*, i);
if (phrase->start == start &&
phrase->end == end &&
strcmp(phrase->cat, cat) == 0 &&
strcmp(phrase->ann, ann) == 0) {
state->matches++;
break;
}
}
state->found++;
}
}
static void
pgf_metrics_lzn_symbol_meta(PgfLinFuncs** funcs, PgfMetaId meta_id)
{
PgfMetricsLznState* state = gu_container(funcs, PgfMetricsLznState, funcs);
pgf_metrics_put_space(state);
if (state->out != NULL)
gu_putc('?', state->out, state->err);
state->pos += 1;
}
static PgfLinFuncs pgf_metrics_lin_funcs1 = {
.symbol_token = pgf_metrics_lzn_symbol_token,
.begin_phrase = pgf_metrics_lzn_begin_phrase,
.end_phrase = pgf_metrics_lzn_end_phrase1,
.symbol_ne = pgf_metrics_symbol_ne,
.symbol_bind = pgf_metrics_symbol_bind,
.symbol_capit = NULL,
.symbol_meta = pgf_metrics_lzn_symbol_meta
};
static PgfLinFuncs pgf_metrics_lin_funcs2 = {
.symbol_token = pgf_metrics_lzn_symbol_token,
.begin_phrase = pgf_metrics_lzn_begin_phrase,
.end_phrase = pgf_metrics_lzn_end_phrase2,
.symbol_ne = pgf_metrics_symbol_ne,
.symbol_bind = pgf_metrics_symbol_bind,
.symbol_capit = NULL,
.symbol_meta = pgf_metrics_lzn_symbol_meta
};
PGF_API bool
pgf_parseval(PgfConcr* concr, PgfExpr expr, PgfType* type,
double *precision, double *recall, double *exact)
{
GuPool* pool = gu_new_pool();
GuExn* err = gu_new_exn(pool);
GuEnum* en_lins1 =
pgf_lzr_concretize(concr, expr, err, pool);
if (!gu_ok(err)) {
gu_pool_free(pool);
return false;
}
PgfCncTree ctree1 = gu_next(en_lins1, PgfCncTree, pool);
if (gu_variant_is_null(ctree1)) {
gu_pool_free(pool);
return false;
}
GuStringBuf* sbuf =
gu_new_string_buf(pool);
PgfMetricsLznState state;
state.bind = true;
state.out = gu_string_buf_out(sbuf);
state.err = gu_new_exn(pool);
state.funcs = &pgf_metrics_lin_funcs1;
state.pos = 0;
state.marks = gu_new_buf(int, pool);
state.phrases = gu_new_buf(PgfPhrase*, pool);
state.matches = 0;
state.found = 0;
state.pool = pool;
pgf_lzr_linearize(concr, ctree1, 0, &state.funcs, pool);
if (!gu_ok(state.err)) {
gu_pool_free(pool);
return false;
}
GuString sentence =
gu_string_buf_freeze(sbuf, pool);
GuEnum* en_trees =
pgf_parse(concr, type, sentence,
state.err, pool, pool);
PgfExprProb* ep = gu_next(en_trees, PgfExprProb*, pool);
if (ep == NULL) {
gu_pool_free(pool);
return false;
}
GuEnum* en_lins2 =
pgf_lzr_concretize(concr, ep->expr, err, pool);
PgfCncTree ctree2 = gu_next(en_lins2, PgfCncTree, pool);
if (gu_variant_is_null(ctree2)) {
gu_pool_free(pool);
return false;
}
state.funcs = &pgf_metrics_lin_funcs2;
state.bind = true;
state.out = NULL;
state.pos = 0;
pgf_lzr_linearize(concr, ctree2, 0, &state.funcs, pool);
*precision = ((double) state.matches)/((double) state.found);
*recall = ((double) state.matches)/((double) gu_buf_length(state.phrases));
*exact = pgf_expr_eq(expr, ep->expr) ? 1 : 0;
gu_pool_free(pool);
return true;
}

View File

@@ -1,338 +0,0 @@
#include <pgf/pgf.h>
#include <pgf/data.h>
#include <pgf/expr.h>
#include <pgf/reader.h>
#include <pgf/writer.h>
#include <pgf/linearizer.h>
#include <gu/file.h>
#include <gu/string.h>
#include <gu/enum.h>
#include <stdio.h>
#include <math.h>
PGF_API PgfPGF*
pgf_read(const char* fpath,
GuPool* pool, GuExn* err)
{
FILE* infile = fopen(fpath, "rb");
if (infile == NULL) {
gu_raise_errno(err);
return NULL;
}
GuPool* tmp_pool = gu_new_pool();
// Create an input stream from the input file
GuIn* in = gu_file_in(infile, tmp_pool);
PgfReader* rdr = pgf_new_reader(in, pool, tmp_pool, err);
PgfPGF* pgf = pgf_read_pgf(rdr);
pgf_reader_done(rdr, pgf);
gu_pool_free(tmp_pool);
fclose(infile);
return pgf;
}
PGF_API PgfPGF*
pgf_read_in(GuIn* in,
GuPool* pool, GuPool* tmp_pool, GuExn* err)
{
PgfReader* rdr = pgf_new_reader(in, pool, tmp_pool, err);
PgfPGF* pgf = pgf_read_pgf(rdr);
pgf_reader_done(rdr, pgf);
return pgf;
}
PGF_API_DECL void
pgf_write(PgfPGF* pgf, size_t n_concrs, PgfConcr** concrs, const char* fpath, GuExn* err)
{
FILE* outfile = fopen(fpath, "wb");
if (outfile == NULL) {
gu_raise_errno(err);
return;
}
GuPool* tmp_pool = gu_local_pool();
// Create an input stream from the input file
GuOut* out = gu_file_out(outfile, tmp_pool);
PgfWriter* wtr = pgf_new_writer(out, tmp_pool, err);
pgf_write_pgf(pgf, n_concrs, concrs, wtr);
gu_pool_free(tmp_pool);
fclose(outfile);
}
PGF_API void
pgf_concrete_save(PgfConcr* concr, const char* fpath, GuExn* err)
{
FILE* outfile = fopen(fpath, "wb");
if (outfile == NULL) {
gu_raise_errno(err);
return;
}
GuPool* tmp_pool = gu_local_pool();
// Create an input stream from the input file
GuOut* out = gu_file_out(outfile, tmp_pool);
PgfWriter* wtr = pgf_new_writer(out, tmp_pool, err);
pgf_write_concrete(concr, wtr, true);
gu_pool_free(tmp_pool);
fclose(outfile);
}
PGF_API bool
pgf_have_same_abstract(PgfPGF *one, PgfPGF *two)
{
if (strcmp(one->abstract.name, two->abstract.name) != 0)
return false;
size_t n_cats = gu_seq_length(one->abstract.cats);
if (n_cats != gu_seq_length(two->abstract.cats))
return false;
size_t n_funs = gu_seq_length(one->abstract.funs);
if (n_funs != gu_seq_length(two->abstract.funs))
return false;
for (size_t i = 0; i < n_cats; i++) {
PgfAbsCat* cat1 = gu_seq_index(one->abstract.cats, PgfAbsCat, i);
PgfAbsCat* cat2 = gu_seq_index(two->abstract.cats, PgfAbsCat, i);
if (strcmp(cat1->name, cat2->name) != 0)
return false;
}
for (size_t i = 0; i < n_funs; i++) {
PgfAbsFun* fun1 = gu_seq_index(one->abstract.funs, PgfAbsFun, i);
PgfAbsFun* fun2 = gu_seq_index(two->abstract.funs, PgfAbsFun, i);
if (strcmp(fun1->name, fun2->name) != 0)
return false;
if (!pgf_type_eq(fun1->type, fun2->type))
return false;
}
return true;
}
PGF_API GuString
pgf_abstract_name(PgfPGF* pgf)
{
return pgf->abstract.name;
}
PGF_API void
pgf_iter_languages(PgfPGF* pgf, GuMapItor* itor, GuExn* err)
{
size_t n_concrs = gu_seq_length(pgf->concretes);
for (size_t i = 0; i < n_concrs; i++) {
PgfConcr* concr = gu_seq_index(pgf->concretes, PgfConcr, i);
itor->fn(itor, concr->name, &concr, err);
if (!gu_ok(err))
break;
}
}
PGF_API PgfConcr*
pgf_get_language(PgfPGF* pgf, PgfCId lang)
{
return gu_seq_binsearch(pgf->concretes, pgf_concr_order, PgfConcr, lang);
}
PGF_API GuString
pgf_concrete_name(PgfConcr* concr)
{
return concr->name;
}
PGF_API void
pgf_iter_categories(PgfPGF* pgf, GuMapItor* itor, GuExn* err)
{
size_t n_cats = gu_seq_length(pgf->abstract.cats);
for (size_t i = 0; i < n_cats; i++) {
PgfAbsCat* cat = gu_seq_index(pgf->abstract.cats, PgfAbsCat, i);
itor->fn(itor, cat->name, &cat, err);
if (!gu_ok(err))
break;
}
}
PGF_API PgfType*
pgf_start_cat(PgfPGF* pgf, GuPool* pool)
{
PgfFlag* flag =
gu_seq_binsearch(pgf->abstract.aflags, pgf_flag_order, PgfFlag, "startcat");
if (flag != NULL) {
GuVariantInfo i = gu_variant_open(flag->value);
switch (i.tag) {
case PGF_LITERAL_STR: {
PgfLiteralStr *lstr = (PgfLiteralStr *) i.data;
GuPool* tmp_pool = gu_local_pool();
GuIn* in = gu_string_in(lstr->val,tmp_pool);
GuExn* err = gu_new_exn(tmp_pool);
PgfType *type = pgf_read_type(in, pool, tmp_pool, err);
if (!gu_ok(err))
break;
gu_pool_free(tmp_pool);
return type;
}
}
}
PgfType* type = gu_new_flex(pool, PgfType, exprs, 0);
type->hypos = gu_empty_seq();
type->cid = "S";
type->n_exprs = 0;
return type;
}
PGF_API PgfHypos*
pgf_category_context(PgfPGF *gr, PgfCId catname)
{
PgfAbsCat* abscat =
gu_seq_binsearch(gr->abstract.cats, pgf_abscat_order, PgfAbsCat, catname);
if (abscat == NULL) {
return NULL;
}
return abscat->context;
}
PGF_API prob_t
pgf_category_prob(PgfPGF* pgf, PgfCId catname)
{
PgfAbsCat* abscat =
gu_seq_binsearch(pgf->abstract.cats, pgf_abscat_order, PgfAbsCat, catname);
if (abscat == NULL)
return INFINITY;
return abscat->prob;
}
PGF_API GuString*
pgf_category_fields(PgfConcr* concr, PgfCId catname, size_t *n_lins)
{
PgfCncCat* cnccat =
gu_map_get(concr->cnccats, catname, PgfCncCat*);
if (!cnccat) {
*n_lins = 0;
return NULL;
}
*n_lins = cnccat->n_lins;
return &cnccat->labels;
}
PGF_API GuString
pgf_language_code(PgfConcr* concr)
{
PgfFlag* flag =
gu_seq_binsearch(concr->cflags, pgf_flag_order, PgfFlag, "language");
if (flag == NULL)
return NULL;
GuVariantInfo i = gu_variant_open(flag->value);
switch (i.tag) {
case PGF_LITERAL_STR: {
PgfLiteralStr *lstr = (PgfLiteralStr *) i.data;
return lstr->val;
}
}
return NULL;
}
PGF_API void
pgf_iter_functions(PgfPGF* pgf, GuMapItor* itor, GuExn* err)
{
size_t n_funs = gu_seq_length(pgf->abstract.funs);
for (size_t i = 0; i < n_funs; i++) {
PgfAbsFun* fun = gu_seq_index(pgf->abstract.funs, PgfAbsFun, i);
itor->fn(itor, fun->name, &fun, err);
if (!gu_ok(err))
break;
}
}
PGF_API void
pgf_iter_functions_by_cat(PgfPGF* pgf, PgfCId catname,
GuMapItor* itor, GuExn* err)
{
size_t n_funs = gu_seq_length(pgf->abstract.funs);
for (size_t i = 0; i < n_funs; i++) {
PgfAbsFun* fun = gu_seq_index(pgf->abstract.funs, PgfAbsFun, i);
if (strcmp(fun->type->cid, catname) == 0) {
itor->fn(itor, fun->name, &fun, err);
if (!gu_ok(err))
break;
}
}
}
PGF_API PgfType*
pgf_function_type(PgfPGF* pgf, PgfCId funname)
{
PgfAbsFun* absfun =
gu_seq_binsearch(pgf->abstract.funs, pgf_absfun_order, PgfAbsFun, funname);
if (absfun == NULL)
return NULL;
return absfun->type;
}
PGF_API_DECL bool
pgf_function_is_constructor(PgfPGF* pgf, PgfCId funname)
{
PgfAbsFun* absfun =
gu_seq_binsearch(pgf->abstract.funs, pgf_absfun_order, PgfAbsFun, funname);
if (absfun == NULL)
return false;
return (absfun->defns == NULL);
}
PGF_API prob_t
pgf_function_prob(PgfPGF* pgf, PgfCId funname)
{
PgfAbsFun* absfun =
gu_seq_binsearch(pgf->abstract.funs, pgf_absfun_order, PgfAbsFun, funname);
if (absfun == NULL)
return INFINITY;
return absfun->ep.prob;
}
PGF_API GuString
pgf_print_name(PgfConcr* concr, PgfCId id)
{
PgfCId name =
gu_map_get(concr->printnames, id, GuString);
return name;
}
PGF_API int
pgf_has_linearization(PgfConcr* concr, PgfCId id)
{
PgfCncOverloadMap* overl_table =
gu_map_get(concr->fun_indices, id, PgfCncOverloadMap*);
return (overl_table != NULL);
}
PGF_API PgfExprProb*
pgf_fun_get_ep(void* value)
{
PgfAbsFun* absfun = *((PgfAbsFun**) value);
return &absfun->ep;
}

View File

@@ -1,291 +0,0 @@
#ifndef PGF_H_
#define PGF_H_
#include <gu/exn.h>
#include <gu/mem.h>
#include <gu/map.h>
#include <gu/enum.h>
#include <gu/string.h>
#if defined(_MSC_VER)
#if defined(COMPILING_PGF)
#define PGF_API_DECL __declspec(dllexport)
#define PGF_API __declspec(dllexport)
#else
#define PGF_API_DECL __declspec(dllimport)
#define PGF_API ERROR_NOT_COMPILING_LIBPGF
#endif
#define PGF_INTERNAL_DECL
#define PGF_INTERNAL
#else
#define PGF_API_DECL
#define PGF_API
#define PGF_INTERNAL_DECL __attribute__ ((visibility ("hidden")))
#define PGF_INTERNAL __attribute__ ((visibility ("hidden")))
#endif
typedef GuString PgfCId;
typedef GuString PgfToken;
typedef struct PgfPGF PgfPGF;
typedef struct PgfConcr PgfConcr;
#include <pgf/expr.h>
#include <pgf/graphviz.h>
typedef GuEnum PgfExprEnum;
PGF_API_DECL PgfPGF*
pgf_read(const char* fpath,
GuPool* pool, GuExn* err);
PGF_API_DECL PgfPGF*
pgf_read_in(GuIn* in,
GuPool* pool, GuPool* tmp_pool, GuExn* err);
PGF_API_DECL void
pgf_concrete_load(PgfConcr* concr, GuIn* in, GuExn* err);
PGF_API_DECL void
pgf_concrete_unload(PgfConcr* concr);
PGF_API_DECL void
pgf_write(PgfPGF* pgf, size_t n_concrs, PgfConcr** concrs, const char* fpath, GuExn* err);
PGF_API_DECL bool
pgf_have_same_abstract(PgfPGF *one, PgfPGF *two);
PGF_API_DECL GuString
pgf_abstract_name(PgfPGF*);
PGF_API_DECL void
pgf_iter_languages(PgfPGF*, GuMapItor* itor, GuExn* err);
PGF_API_DECL PgfConcr*
pgf_get_language(PgfPGF*, PgfCId lang);
PGF_API_DECL GuString
pgf_concrete_name(PgfConcr*);
PGF_API_DECL GuString
pgf_language_code(PgfConcr* concr);
PGF_API_DECL void
pgf_iter_categories(PgfPGF* pgf, GuMapItor* itor, GuExn* err);
PGF_API_DECL PgfType*
pgf_start_cat(PgfPGF* pgf, GuPool* pool);
PGF_API_DECL PgfHypos*
pgf_category_context(PgfPGF *gr, PgfCId catname);
PGF_API_DECL prob_t
pgf_category_prob(PgfPGF* pgf, PgfCId catname);
PGF_API GuString*
pgf_category_fields(PgfConcr* concr, PgfCId catname, size_t *n_lins);
PGF_API_DECL void
pgf_iter_functions(PgfPGF* pgf, GuMapItor* itor, GuExn* err);
PGF_API_DECL void
pgf_iter_functions_by_cat(PgfPGF* pgf, PgfCId catname,
GuMapItor* itor, GuExn* err);
PGF_API_DECL PgfType*
pgf_function_type(PgfPGF* pgf, PgfCId funname);
PGF_API_DECL bool
pgf_function_is_constructor(PgfPGF* pgf, PgfCId funname);
PGF_API_DECL prob_t
pgf_function_prob(PgfPGF* pgf, PgfCId funname);
PGF_API_DECL GuString
pgf_print_name(PgfConcr*, PgfCId id);
PGF_API_DECL int
pgf_has_linearization(PgfConcr* concr, PgfCId id);
PGF_API_DECL void
pgf_linearize(PgfConcr* concr, PgfExpr expr, GuOut* out, GuExn* err);
typedef struct {
GuString phrase;
size_t n_fids;
int fids[];
} PgfAlignmentPhrase;
PGF_API_DECL GuSeq*
pgf_align_words(PgfConcr* concr, PgfExpr expr,
GuExn* err, GuPool* pool);
PGF_API_DECL bool
pgf_parseval(PgfConcr* concr, PgfExpr expr, PgfType* type,
double *precision, double *recall, double *exact);
PGF_API_DECL PgfExpr
pgf_compute(PgfPGF* pgf, PgfExpr expr, GuExn* err,
GuPool* pool, GuPool* out_pool);
PGF_API_DECL PgfExprEnum*
pgf_generate_all(PgfPGF* pgf, PgfType* ty,
GuExn* err, GuPool* pool, GuPool* out_pool);
typedef struct {
int incomplete; // equal to !=0 if the sentence is incomplete, 0 otherwise
size_t offset;
const char* token_ptr;
size_t token_len;
} PgfParseError;
PGF_API_DECL PgfExprEnum*
pgf_parse(PgfConcr* concr, PgfType* typ, GuString sentence,
GuExn* err, GuPool* pool, GuPool* out_pool);
PGF_API_DECL GuEnum*
pgf_lookup_sentence(PgfConcr* concr, PgfType* typ, GuString sentence, GuPool* pool, GuPool* out_pool);
typedef struct PgfMorphoCallback PgfMorphoCallback;
struct PgfMorphoCallback {
void (*callback)(PgfMorphoCallback* self,
PgfCId lemma, GuString analysis, prob_t prob,
GuExn* err);
};
PGF_API_DECL void
pgf_lookup_morpho(PgfConcr *concr, GuString sentence,
PgfMorphoCallback* callback, GuExn* err);
typedef struct {
size_t pos; // position in Unicode characters
GuString ptr; // pointer into the string
} PgfCohortSpot;
typedef struct {
PgfCohortSpot start;
PgfCohortSpot end;
GuBuf* buf;
} PgfCohortRange;
PGF_API_DECL GuEnum*
pgf_lookup_cohorts(PgfConcr *concr, GuString sentence,
PgfMorphoCallback* callback,
GuPool* pool, GuExn* err);
typedef struct PgfFullFormEntry PgfFullFormEntry;
PGF_API_DECL GuEnum*
pgf_fullform_lexicon(PgfConcr *concr, GuPool* pool);
PGF_API_DECL GuString
pgf_fullform_get_string(PgfFullFormEntry* entry);
PGF_API_DECL void
pgf_fullform_get_analyses(PgfFullFormEntry* entry,
PgfMorphoCallback* callback, GuExn* err);
PGF_API_DECL GuEnum*
pgf_lookup_word_prefix(PgfConcr *concr, GuString prefix,
GuPool* pool, GuExn* err);
typedef GuMap PgfCallbacksMap;
PGF_API_DECL PgfExprEnum*
pgf_parse_with_heuristics(PgfConcr* concr, PgfType* typ,
GuString sentence, double heuristics,
PgfCallbacksMap* callbacks,
GuExn* err,
GuPool* pool, GuPool* out_pool);
typedef struct {
size_t start;
size_t end;
GuString field;
} PgfParseRange;
typedef struct PgfOracleCallback PgfOracleCallback;
struct PgfOracleCallback {
bool (*predict) (PgfOracleCallback* self,
PgfCId cat,
GuString label,
size_t offset);
bool (*complete)(PgfOracleCallback* self,
PgfCId cat,
GuString label,
size_t offset);
PgfExprProb* (*literal)(PgfOracleCallback* self,
PgfCId cat,
GuString label,
size_t* poffset,
GuPool *out_pool);
};
PGF_API_DECL PgfExprEnum*
pgf_parse_with_oracle(PgfConcr* concr, PgfType* typ,
GuString sentence,
PgfOracleCallback* oracle,
GuExn* err,
GuPool* pool, GuPool* out_pool);
typedef struct {
PgfToken tok;
PgfCId cat;
PgfCId fun;
prob_t prob;
} PgfTokenProb;
PGF_API_DECL GuEnum*
pgf_complete(PgfConcr* concr, PgfType* type, GuString string,
GuString prefix, GuExn* err, GuPool* pool);
typedef struct PgfLiteralCallback PgfLiteralCallback;
struct PgfLiteralCallback {
PgfExprProb* (*match)(PgfLiteralCallback* self, PgfConcr* concr,
GuString ann,
GuString sentence, size_t* poffset,
GuPool *out_pool);
GuEnum* (*predict)(PgfLiteralCallback* self, PgfConcr* concr,
GuString ann,
GuString prefix,
GuPool *out_pool);
};
PGF_API_DECL PgfCallbacksMap*
pgf_new_callbacks_map(PgfConcr* concr, GuPool *pool);
PGF_API_DECL void
pgf_callbacks_map_add_literal(PgfConcr* concr, PgfCallbacksMap* callbacks,
PgfCId cat, PgfLiteralCallback* callback);
PGF_API_DECL void
pgf_print(PgfPGF* pgf, size_t n_concrs, PgfConcr** concrs,
GuOut* out, GuExn* err);
PGF_API_DECL void
pgf_check_expr(PgfPGF* gr, PgfExpr* pe, PgfType* ty,
GuExn* exn, GuPool* pool);
PGF_API_DECL PgfType*
pgf_infer_expr(PgfPGF* gr, PgfExpr* pe,
GuExn* exn, GuPool* pool);
PGF_API_DECL void
pgf_check_type(PgfPGF* gr, PgfType** ty,
GuExn* exn, GuPool* pool);
// internal
PGF_API_DECL PgfExprProb*
pgf_fun_get_ep(void* value);
#endif // PGF_H_

View File

@@ -1,438 +0,0 @@
#include <pgf/data.h>
#include <stdlib.h>
typedef struct {
GuMapItor fn;
GuOut* out;
} PgfPrintFn;
static void
pgf_print_flags(PgfFlags* flags, int indent, GuOut *out, GuExn* err)
{
size_t n_flags = gu_seq_length(flags);
for (size_t i = 0; i < n_flags; i++) {
PgfFlag* flag = gu_seq_index(flags, PgfFlag, i);
for (int k = 0; k < indent; k++) {
gu_putc(' ', out, err);
}
gu_puts("flag ", out, err);
pgf_print_cid(flag->name, out, err);
gu_puts(" = ", out, err);
pgf_print_literal(flag->value, out, err);
gu_puts(";\n", out, err);
}
}
static void
pgf_print_abscats(PgfAbsCats* abscats, GuOut *out, GuExn* err)
{
size_t n_cats = gu_seq_length(abscats);
for (size_t i = 0; i < n_cats; i++) {
PgfAbsCat *abscat = gu_seq_index(abscats, PgfAbsCat, i);
gu_puts(" cat ", out, err);
pgf_print_cid(abscat->name, out, err);
PgfPrintContext* ctxt = NULL;
size_t n_hypos = gu_seq_length(abscat->context);
for (size_t i = 0; i < n_hypos; i++) {
PgfHypo* hypo = gu_seq_index(abscat->context, PgfHypo, i);
gu_putc(' ', out, err);
ctxt = pgf_print_hypo(hypo, ctxt, 4, out, err);
}
while (ctxt != NULL) {
PgfPrintContext* next = ctxt->next;
free(ctxt);
ctxt = next;
}
gu_printf(out, err, " ; -- %f\n", abscat->prob);
}
}
static void
pgf_print_absfuns(PgfAbsFuns* absfuns, GuOut *out, GuExn* err)
{
size_t n_funs = gu_seq_length(absfuns);
for (size_t i = 0; i < n_funs; i++) {
PgfAbsFun *absfun = gu_seq_index(absfuns, PgfAbsFun, i);
gu_puts((absfun->defns == NULL) ? " data " : " fun ", out, err);
pgf_print_cid(absfun->name, out, err);
gu_puts(" : ", out, err);
pgf_print_type(absfun->type, NULL, 0, out, err);
gu_printf(out, err, " ; -- %f\n", absfun->ep.prob);
}
}
static void
pgf_print_abstract(PgfAbstr* abstr, GuOut* out, GuExn* err)
{
gu_puts("abstract ", out, err);
pgf_print_cid(abstr->name, out, err);
gu_puts(" {\n", out, err);
pgf_print_flags(abstr->aflags, 2, out, err);
pgf_print_abscats(abstr->cats, out, err);
pgf_print_absfuns(abstr->funs, out, err);
gu_puts("}\n", out, err);
}
PGF_INTERNAL void
pgf_print_fid(int fid, GuOut* out, GuExn* err)
{
if (fid == -1)
gu_puts("CString", out, err);
else if (fid == -2)
gu_puts("CInt", out, err);
else if (fid == -3)
gu_puts("CFloat", out, err);
else if (fid == -4)
gu_puts("CVar", out, err);
else if (fid == -5)
gu_puts("CStart", out, err);
else
gu_printf(out, err, "C%d", fid);
}
PGF_INTERNAL void
pgf_print_production_args(PgfPArgs* args,
GuOut* out, GuExn* err)
{
size_t n_args = gu_seq_length(args);
for (size_t j = 0; j < n_args; j++) {
if (j > 0)
gu_putc(',',out,err);
PgfPArg arg = gu_seq_get(args, PgfPArg, j);
if (arg.hypos != NULL &&
gu_seq_length(arg.hypos) > 0) {
size_t n_hypos = gu_seq_length(arg.hypos);
for (size_t k = 0; k < n_hypos; k++) {
PgfCCat *hypo = gu_seq_get(arg.hypos, PgfCCat*, k);
pgf_print_fid(hypo->fid, out, err);
gu_putc(' ',out,err);
}
gu_puts("-> ",out,err);
}
pgf_print_fid(arg.ccat->fid, out, err);
}
}
PGF_INTERNAL void
pgf_print_production(int fid, PgfProduction prod,
GuOut *out, GuExn* err)
{
pgf_print_fid(fid, out, err);
gu_puts(" -> ", out, err);
GuVariantInfo i = gu_variant_open(prod);
switch (i.tag) {
case PGF_PRODUCTION_APPLY: {
PgfProductionApply* papp = i.data;
gu_printf(out,err,"F%d(",papp->fun->funid);
if (papp->fun->ep != NULL) {
pgf_print_expr(papp->fun->ep->expr, NULL, 0, out, err);
} else {
PgfPArg* parg = gu_seq_index(papp->args, PgfPArg, 0);
gu_printf(out,err,"linref %s", parg->ccat->cnccat->abscat->name);
}
gu_printf(out,err,")[");
pgf_print_production_args(papp->args,out,err);
gu_printf(out,err,"]\n");
break;
}
case PGF_PRODUCTION_COERCE: {
PgfProductionCoerce* pcoerce = i.data;
gu_puts("_[",out,err);
pgf_print_fid(pcoerce->coerce->fid, out, err);
gu_puts("]\n",out,err);
break;
}
case PGF_PRODUCTION_EXTERN: {
PgfProductionExtern* pext = i.data;
gu_printf(out,err,"<extern>(");
pgf_print_expr(pext->ep->expr, NULL, 0, out, err);
gu_printf(out,err,")[]\n");
break;
}
default:
gu_impossible();
}
}
static void
pgf_print_productions(GuMapItor* fn, const void* key, void* value,
GuExn* err)
{
PgfPrintFn* clo = (PgfPrintFn*) fn;
int fid = *((int *) key);
PgfCCat* ccat = *((PgfCCat**) value);
GuOut *out = clo->out;
if (ccat->prods != NULL) {
size_t n_prods = gu_seq_length(ccat->prods);
for (size_t i = 0; i < n_prods; i++) {
PgfProduction prod = gu_seq_get(ccat->prods, PgfProduction, i);
pgf_print_production(fid, prod, out, err);
}
}
}
static void
pgf_print_lindefs(GuMapItor* fn, const void* key, void* value,
GuExn* err)
{
PgfPrintFn* clo = (PgfPrintFn*) fn;
int fid = *((int *) key);
PgfCCat* ccat = *((PgfCCat**) value);
GuOut *out = clo->out;
if (ccat->lindefs != NULL) {
size_t n_lindefs = gu_seq_length(ccat->lindefs);
for (size_t i = 0; i < n_lindefs; i++) {
PgfCncFun* fun = gu_seq_get(ccat->lindefs, PgfCncFun*, i);
gu_puts(" ",out,err);
pgf_print_fid(fid, out, err);
gu_printf(out,err," -> F%d[CVar]\n",fun->funid);
}
}
}
static void
pgf_print_linrefs(GuMapItor* fn, const void* key, void* value,
GuExn* err)
{
PgfPrintFn* clo = (PgfPrintFn*) fn;
int fid = *((int *) key);
PgfCCat* ccat = *((PgfCCat**) value);
GuOut *out = clo->out;
if (ccat->linrefs != NULL) {
size_t n_linrefs = gu_seq_length(ccat->linrefs);
for (size_t i = 0; i < n_linrefs; i++) {
PgfCncFun* fun = gu_seq_get(ccat->linrefs, PgfCncFun*, i);
gu_printf(out,err," CVar -> F%d[",fun->funid);
pgf_print_fid(fid, out, err);
gu_puts("]\n", out, err);
}
}
}
static void
pgf_print_cncfun(PgfCncFun *cncfun, PgfSequences* sequences,
GuOut *out, GuExn *err)
{
gu_printf(out,err," F%d := (", cncfun->funid);
for (size_t i = 0; i < cncfun->n_lins; i++) {
if (i > 0) gu_putc(',', out, err);
PgfSequence* seq = cncfun->lins[i];
gu_printf(out,err,"S%d", (seq - ((PgfSequence*) gu_seq_data(sequences))));
}
gu_puts(")", out, err);
if (cncfun->absfun != NULL) {
gu_puts(" [", out, err);
pgf_print_cid(cncfun->absfun->name, out, err);
gu_puts("]", out, err);
}
gu_puts("\n", out, err);
}
static void
pgf_print_token(PgfToken tok, GuOut *out, GuExn *err)
{
gu_putc('"', out, err);
gu_string_write(tok, out, err);
gu_putc('"', out, err);
}
static void
pgf_print_symbols(PgfSymbols* syms, GuOut *out, GuExn *err);
PGF_INTERNAL void
pgf_print_symbol(PgfSymbol sym, GuOut *out, GuExn *err)
{
switch (gu_variant_tag(sym)) {
case PGF_SYMBOL_CAT: {
PgfSymbolCat* scat = gu_variant_data(sym);
gu_printf(out, err, "<%d,%d>", scat->d, scat->r);
break;
}
case PGF_SYMBOL_KS: {
PgfSymbolKS* sks = gu_variant_data(sym);
pgf_print_token(sks->token, out, err);
break;
}
case PGF_SYMBOL_KP: {
PgfSymbolKP* skp = gu_variant_data(sym);
gu_puts("pre {", out, err);
pgf_print_symbols(skp->default_form, out, err);
for (size_t i = 0; i < skp->n_forms; i++) {
gu_puts("; ", out, err);
pgf_print_symbols(skp->forms[i].form, out, err);
gu_puts(" / ", out, err);
size_t n_prefixes = gu_seq_length(skp->forms[i].prefixes);
for (size_t j = 0; j < n_prefixes; j++) {
if (j > 0) gu_putc(' ', out, err);
GuString prefix = gu_seq_get(skp->forms[i].prefixes, GuString, j);
gu_putc('"', out, err);
gu_string_write(prefix, out, err);
gu_putc('"', out, err);
}
}
gu_puts("}", out, err);
break;
}
case PGF_SYMBOL_LIT: {
PgfSymbolLit *slit = gu_variant_data(sym);
gu_printf(out, err, "{%d,%d}", slit->d, slit->r);
break;
}
case PGF_SYMBOL_VAR: {
PgfSymbolVar *svar = gu_variant_data(sym);
gu_printf(out, err, "<%d,$%d>", svar->d, svar->r);
break;
}
case PGF_SYMBOL_NE: {
gu_puts("nonExist", out, err);
break;
}
case PGF_SYMBOL_BIND: {
gu_puts("BIND", out, err);
break;
}
case PGF_SYMBOL_SOFT_BIND: {
gu_puts("SOFT_BIND", out, err);
break;
}
case PGF_SYMBOL_SOFT_SPACE: {
gu_puts("SOFT_SPACE", out, err);
break;
}
case PGF_SYMBOL_CAPIT: {
gu_puts("CAPIT", out, err);
break;
}
case PGF_SYMBOL_ALL_CAPIT: {
gu_puts("ALL_CAPIT", out, err);
break;
}
default:
gu_impossible();
}
}
static void
pgf_print_symbols(PgfSymbols* syms, GuOut *out, GuExn *err)
{
int n_syms = gu_seq_length(syms);
for (int i = 0; i < n_syms; i++) {
if (i > 0) gu_putc(' ', out, err);
PgfSymbol sym = gu_seq_get(syms, PgfSymbol, i);
pgf_print_symbol(sym, out, err);
}
}
static void
pgf_print_cnccat(GuMapItor* fn, const void* key, void* value,
GuExn* err)
{
PgfPrintFn* clo = (PgfPrintFn*) fn;
PgfCId name = (PgfCId) key;
PgfCncCat* cnccat = *((PgfCncCat**) value);
GuOut *out = clo->out;
gu_puts(" ", out, err);
pgf_print_cid(name, out, err);
gu_puts(" :=\n", out, err);
PgfCCat *start = gu_seq_get(cnccat->cats, PgfCCat*, 0);
PgfCCat *end = gu_seq_get(cnccat->cats, PgfCCat*, gu_seq_length(cnccat->cats)-1);
gu_puts(" range [", out, err);
pgf_print_fid(start->fid, out, err);
gu_puts("..", out, err);
pgf_print_fid(end->fid, out, err);
gu_puts("]\n", out, err);
gu_puts(" labels [", out, err);
for (size_t i = 0; i < cnccat->n_lins; i++) {
if (i > 0) {
gu_puts("\n ", out, err);
}
gu_string_write(cnccat->labels[i], out, err);
}
gu_puts("]\n", out, err);
}
static void
pgf_print_concrete(PgfConcr* concr, GuOut* out, GuExn* err)
{
gu_puts("concrete ", out, err);
pgf_print_cid(concr->name, out, err);
gu_puts(" {\n", out, err);
pgf_print_flags(concr->cflags, 2, out, err);
gu_puts(" productions\n", out, err);
PgfPrintFn clo2 = { { pgf_print_productions }, out };
gu_map_iter(concr->ccats, &clo2.fn, err);
gu_puts(" lindefs\n", out, err);
PgfPrintFn clo3 = { { pgf_print_lindefs }, out };
gu_map_iter(concr->ccats, &clo3.fn, err);
gu_puts(" linrefs\n", out, err);
PgfPrintFn clo4 = { { pgf_print_linrefs }, out };
gu_map_iter(concr->ccats, &clo4.fn, err);
gu_puts(" lin\n", out, err);
size_t n_funs = gu_seq_length(concr->cncfuns);
for (size_t i = 0; i < n_funs; i++) {
PgfCncFun* cncfun = gu_seq_get(concr->cncfuns, PgfCncFun*, i);
pgf_print_cncfun(cncfun, concr->sequences, out, err);
}
gu_puts(" sequences\n", out, err);
size_t n_seqs = gu_seq_length(concr->sequences);
for (size_t i = 0; i < n_seqs; i++) {
gu_printf(out,err," S%d := ", i);
PgfSymbols* syms = gu_seq_index(concr->sequences, PgfSequence, i)->syms;
pgf_print_symbols(syms, out, err);
gu_putc('\n', out, err);
}
gu_puts(" categories\n", out, err);
PgfPrintFn clo5 = { { pgf_print_cnccat }, out };
gu_map_iter(concr->cnccats, &clo5.fn, err);
gu_puts("}\n", out, err);
}
PGF_API void
pgf_print(PgfPGF* pgf, size_t n_concrs, PgfConcr** concrs, GuOut* out, GuExn* err)
{
pgf_print_flags(pgf->gflags, 0, out, err);
pgf_print_abstract(&pgf->abstract, out, err);
for (size_t i = 0; i < n_concrs; i++) {
pgf_print_concrete(concrs[i], out, err);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,73 +0,0 @@
#ifndef READER_H_
#define READER_H_
#include <gu/exn.h>
#include <gu/mem.h>
#include <gu/in.h>
// general reader interface
typedef struct {
GuIn* in;
GuExn* err;
GuPool* opool;
GuPool* tmp_pool;
GuBuf* non_lexical_buf;
struct PgfJitState* jit_state;
} PgfReader;
PGF_INTERNAL_DECL PgfReader*
pgf_new_reader(GuIn* in, GuPool* opool, GuPool* tmp_pool, GuExn* err);
PGF_INTERNAL_DECL uint8_t
pgf_read_tag(PgfReader* rdr);
PGF_INTERNAL_DECL uint32_t
pgf_read_uint(PgfReader* rdr);
PGF_INTERNAL_DECL int32_t
pgf_read_int(PgfReader* rdr);
PGF_INTERNAL_DECL GuString
pgf_read_string(PgfReader* rdr);
PGF_INTERNAL_DECL double
pgf_read_double(PgfReader* rdr);
PGF_INTERNAL_DECL size_t
pgf_read_len(PgfReader* rdr);
PGF_INTERNAL_DECL PgfCId
pgf_read_cid(PgfReader* rdr, GuPool* pool);
PGF_INTERNAL_DECL PgfPGF*
pgf_read_pgf(PgfReader* rdr);
PGF_INTERNAL_DECL void
pgf_reader_done(PgfReader* rdr, PgfPGF* pgf);
// JIT specific interface
#ifdef PGF_REASONER_H_
typedef struct PgfJitState PgfJitState;
PGF_INTERNAL_DECL PgfJitState*
pgf_new_jit(PgfReader* rdr);
PGF_INTERNAL_DECL PgfEvalGates*
pgf_jit_gates(PgfReader* rdr);
PGF_INTERNAL_DECL void
pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr,
PgfAbsCat* abscat);
PGF_INTERNAL_DECL void
pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
PgfAbsFun* absfun);
PGF_INTERNAL_DECL void
pgf_jit_done(PgfReader* state, PgfAbstr* abstr);
#endif
#endif // READER_H_

View File

@@ -1,475 +0,0 @@
#include <pgf/pgf.h>
#include <pgf/data.h>
#include <pgf/reasoner.h>
#include <gu/file.h>
//#define PGF_REASONER_DEBUG
typedef struct {
GuBuf* parents;
GuBuf* exprs;
prob_t outside_prob;
} PgfAnswers;
#ifdef PGF_REASONER_DEBUG
typedef void (*PgfStatePrinter)(PgfReasoner* rs, PgfReasonerState* st,
GuOut* out, GuExn* err,
GuPool* tmp_pool);
#endif
struct PgfReasonerState {
PgfClosure header;
#ifdef PGF_REASONER_DEBUG
PgfStatePrinter print;
#endif
prob_t prob;
};
struct PgfExprState {
// base must be the first field in order to be able to cast
// from PgfExprState to PgfReasonerState
PgfReasonerState base;
PgfAnswers* answers;
PgfExpr expr;
#ifdef PGF_REASONER_DEBUG
size_t n_args;
size_t arg_idx;
#endif
};
typedef struct {
// base must be the first field in order to be able to cast
// from PgfCombine1State to PgfReasonerState
PgfReasonerState base;
GuBuf* exprs;
PgfExprState* parent;
size_t n_choices;
size_t choice;
} PgfCombine1State;
typedef struct {
// base must be the first field in order to be able to cast
// from PgfCombine2State to PgfReasonerState
PgfReasonerState base;
GuBuf* parents;
PgfExprProb* ep;
size_t n_choices;
size_t choice;
} PgfCombine2State;
static int
cmp_expr_state(GuOrder* self, const void* a, const void* b)
{
PgfReasonerState *st1 = *((PgfReasonerState **) a);
PgfReasonerState *st2 = *((PgfReasonerState **) b);
if (st1->prob < st2->prob)
return -1;
else if (st1->prob > st2->prob)
return 1;
else
return 0;
}
static GuOrder
pgf_expr_state_order = { cmp_expr_state };
#ifdef PGF_REASONER_DEBUG
static void
pgf_print_parent_state(PgfReasoner* rs, PgfExprState* st,
GuOut* out, GuExn* err, GuBuf* stack)
{
gu_buf_push(stack, int, (st->n_args - st->arg_idx - 1));
PgfExprState* parent = gu_buf_get(st->answers->parents, PgfExprState*, 0);
if (&parent->base.header != rs->start)
pgf_print_parent_state(rs, parent, out, err, stack);
gu_puts(" (", out, err);
pgf_print_expr(st->expr, NULL, 0, out, err);
}
static void
pgf_print_expr_state(PgfReasoner* rs, PgfExprState* st,
GuOut* out, GuExn* err, GuPool* tmp_pool)
{
gu_printf(out, err, "[%f] ", st->base.prob);
GuBuf* stack = gu_new_buf(int, tmp_pool);
if (st->n_args > 0)
gu_buf_push(stack, int, st->n_args - st->arg_idx);
PgfExprState* cont =
gu_buf_get(st->answers->parents, PgfExprState*, 0);
if (&cont->base.header != rs->start)
pgf_print_parent_state(rs, cont, out, err, stack);
if (st->n_args > 0)
gu_puts(" (", out, err);
else
gu_puts(" ", out, err);
pgf_print_expr(st->expr, NULL, 0, out, err);
size_t n_counts = gu_buf_length(stack);
for (size_t i = 0; i < n_counts; i++) {
int count = gu_buf_get(stack, int, i);
while (count-- > 0)
gu_puts(" ?", out, err);
gu_puts(")", out, err);
}
gu_puts("\n", out, err);
}
#endif
static PgfExprState*
pgf_combine1_to_expr(PgfCombine1State* st, GuPool* pool, GuPool* out_pool) {
PgfExprProb* ep =
gu_buf_get(st->exprs, PgfExprProb*, st->choice);
PgfExprState* nst = gu_new(PgfExprState, pool);
nst->base.header.code = st->parent->base.header.code;
nst->base.prob = st->base.prob;
nst->answers = st->parent->answers;
nst->expr =
gu_new_variant_i(out_pool, PGF_EXPR_APP,
PgfExprApp,
.fun = st->parent->expr,
.arg = ep->expr);
#ifdef PGF_REASONER_DEBUG
nst->base.print = (PgfStatePrinter) pgf_print_expr_state;
nst->n_args = st->parent->n_args;
nst->arg_idx = st->parent->arg_idx+1;
#endif
return nst;
}
static PgfExprState*
pgf_combine2_to_expr(PgfReasoner* rs, PgfCombine2State* st,
GuPool* pool, GuPool* out_pool)
{
PgfExprState* parent =
gu_buf_get(st->parents, PgfExprState*, st->choice);
if (&parent->base.header == rs->start)
return NULL;
PgfExprState* nst =
gu_new(PgfExprState, pool);
nst->base.header.code = parent->base.header.code;
nst->base.prob = st->base.prob;
nst->answers = parent->answers;
nst->expr =
gu_new_variant_i(out_pool, PGF_EXPR_APP,
PgfExprApp,
.fun = parent->expr,
.arg = st->ep->expr);
#ifdef PGF_REASONER_DEBUG
nst->base.print = (PgfStatePrinter) pgf_print_expr_state;
nst->n_args = parent->n_args;
nst->arg_idx = parent->arg_idx+1;
#endif
return nst;
}
#ifdef PGF_REASONER_DEBUG
static void
pgf_print_combine1_state(PgfReasoner* rs, PgfCombine1State* st,
GuOut* out, GuExn* err, GuPool* tmp_pool)
{
PgfExprState* nst = pgf_combine1_to_expr(st, tmp_pool, tmp_pool);
pgf_print_expr_state(rs, nst, out, err, tmp_pool);
}
static void
pgf_print_combine2_state(PgfReasoner* rs, PgfCombine2State* st,
GuOut* out, GuExn* err, GuPool* tmp_pool)
{
PgfExprState* nst = pgf_combine2_to_expr(rs, st, tmp_pool, tmp_pool);
if (nst != NULL)
pgf_print_expr_state(rs, nst, out, err, tmp_pool);
}
#endif
PGF_INTERNAL void
pgf_reasoner_combine1(PgfReasoner* rs, PgfClosure* closure)
{
PgfCombine1State* st = (PgfCombine1State*) closure;
PgfExprState* nst = pgf_combine1_to_expr(st, rs->pool, rs->out_pool);
rs->eval_gates->enter(rs, &nst->base.header);
st->choice++;
if (st->choice < st->n_choices) {
PgfExprProb* ep =
gu_buf_get(st->exprs, PgfExprProb*, st->choice);
st->base.prob = st->parent->base.prob + ep->prob;
gu_buf_heap_push(rs->pqueue, &pgf_expr_state_order, &st);
}
}
PGF_INTERNAL void
pgf_reasoner_try_first(PgfReasoner* rs, PgfExprState* parent, PgfAbsFun* absfun)
{
PgfCId cat = absfun->type->cid;
PgfAnswers* answers = gu_map_get(rs->table, cat, PgfAnswers*);
if (answers == NULL) {
answers = gu_new(PgfAnswers, rs->pool);
answers->parents = gu_new_buf(PgfExprState*, rs->pool);
answers->exprs = gu_new_buf(PgfExprProb*, rs->pool);
answers->outside_prob = parent->base.prob;
gu_map_put(rs->table, cat, PgfAnswers*, answers);
}
gu_buf_push(answers->parents, PgfExprState*, parent);
if (gu_buf_length(answers->parents) == 1) {
PgfExprState* st = gu_new(PgfExprState, rs->pool);
st->base.header.code = absfun->predicate;
st->base.prob = answers->outside_prob + absfun->ep.prob;
st->answers = answers;
st->expr = absfun->ep.expr;
#ifdef PGF_REASONER_DEBUG
st->base.print = (PgfStatePrinter) pgf_print_expr_state;
st->n_args = gu_seq_length(absfun->type->hypos);
st->arg_idx = 0;
#endif
gu_buf_heap_push(rs->pqueue, &pgf_expr_state_order, &st);
} else {
size_t n_exprs = gu_buf_length(answers->exprs);
if (n_exprs > 0) {
PgfExprProb* ep =
gu_buf_get(answers->exprs, PgfExprProb*, 0);
PgfCombine1State* nst = gu_new(PgfCombine1State, rs->pool);
nst->base.header.code = rs->eval_gates->combine1;
nst->base.prob = parent->base.prob + ep->prob;
nst->exprs = answers->exprs;
nst->choice = 0;
nst->n_choices = gu_buf_length(answers->exprs);
nst->parent = parent;
#ifdef PGF_REASONER_DEBUG
nst->base.print = (PgfStatePrinter) pgf_print_combine1_state;
#endif
gu_buf_heap_push(rs->pqueue, &pgf_expr_state_order, &nst);
}
}
}
PGF_INTERNAL void
pgf_reasoner_try_else(PgfReasoner* rs, PgfExprState* prev, PgfAbsFun* absfun)
{
PgfExprState *st = gu_new(PgfExprState, rs->pool);
st->base.header.code = absfun->predicate;
st->base.prob = prev->answers->outside_prob + absfun->ep.prob;
st->answers = prev->answers;
st->expr = absfun->ep.expr;
#ifdef PGF_REASONER_DEBUG
st->base.print = (PgfStatePrinter) pgf_print_expr_state;
st->n_args = gu_seq_length(absfun->type->hypos);
st->arg_idx = 0;
#endif
gu_buf_heap_push(rs->pqueue, &pgf_expr_state_order, &st);
}
PGF_INTERNAL void
pgf_reasoner_combine2(PgfReasoner* rs, PgfClosure* closure)
{
PgfCombine2State* st = (PgfCombine2State*) closure;
PgfExprState* nst = pgf_combine2_to_expr(rs, st, rs->pool, rs->out_pool);
if (nst != NULL) {
rs->eval_gates->enter(rs, &nst->base.header);
}
st->choice++;
if (st->choice < st->n_choices) {
PgfExprState* parent =
gu_buf_get(st->parents, PgfExprState*, st->choice);
st->base.prob = parent->base.prob + st->ep->prob;
gu_buf_heap_push(rs->pqueue, &pgf_expr_state_order, &st);
}
}
PGF_INTERNAL void
pgf_reasoner_complete(PgfReasoner* rs, PgfExprState* st)
{
PgfExprProb* ep = gu_new(PgfExprProb, rs->out_pool);
ep->prob = st->base.prob - st->answers->outside_prob;
ep->expr = st->expr;
gu_buf_push(st->answers->exprs, PgfExprProb*, ep);
PgfCombine2State* nst = gu_new(PgfCombine2State, rs->pool);
nst->base.header.code = rs->eval_gates->combine2;
nst->base.prob = st->base.prob;
nst->parents = st->answers->parents;
nst->choice = 0;
nst->n_choices = gu_buf_length(st->answers->parents);
nst->ep = ep;
#ifdef PGF_REASONER_DEBUG
nst->base.print = (PgfStatePrinter) pgf_print_combine2_state;
#endif
rs->eval_gates->enter(rs, &nst->base.header);
}
PGF_INTERNAL void
pgf_reasoner_try_constant(PgfReasoner* rs, PgfExprState* prev, PgfAbsFun* absfun)
{
pgf_reasoner_try_else(rs, prev, absfun);
pgf_reasoner_complete(rs, prev);
}
static void
pgf_reasoner_mk_literal(PgfReasoner* rs, PgfExprState* parent,
GuString cat, PgfExpr expr)
{
PgfAnswers* answers = gu_map_get(rs->table, cat, PgfAnswers*);
if (answers == NULL) {
answers = gu_new(PgfAnswers, rs->pool);
answers->parents = gu_new_buf(PgfExprState*, rs->pool);
answers->exprs = gu_new_buf(PgfExprProb*, rs->pool);
answers->outside_prob = parent->base.prob;
gu_map_put(rs->table, cat, PgfAnswers*, answers);
}
gu_buf_push(answers->parents, PgfExprState*, parent);
if (gu_buf_length(answers->parents) == 1) {
PgfExprProb* ep = gu_new(PgfExprProb, rs->out_pool);
ep->prob = 0;
ep->expr = expr;
gu_buf_push(answers->exprs, PgfExprProb*, ep);
}
if (&parent->base.header == rs->start)
return;
PgfExprProb* ep =
gu_buf_get(answers->exprs, PgfExprProb*, 0);
parent->expr =
gu_new_variant_i(rs->out_pool,
PGF_EXPR_APP,
PgfExprApp,
parent->expr,
ep->expr);
#ifdef PGF_REASONER_DEBUG
parent->arg_idx++;
#endif
parent->base.prob += ep->prob;
gu_buf_heap_push(rs->pqueue, &pgf_expr_state_order, &parent);
}
PGF_INTERNAL void
pgf_reasoner_mk_string(PgfReasoner* rs, PgfExprState* parent)
{
pgf_reasoner_mk_literal(rs, parent, "String",
pgf_expr_string("__mock_string__", rs->out_pool));
}
PGF_INTERNAL void
pgf_reasoner_mk_int(PgfReasoner* rs, PgfExprState* parent)
{
pgf_reasoner_mk_literal(rs, parent, "Int",
pgf_expr_int(999, rs->out_pool));
}
PGF_INTERNAL void
pgf_reasoner_mk_float(PgfReasoner* rs, PgfExprState* parent)
{
pgf_reasoner_mk_literal(rs, parent, "Float",
pgf_expr_float(999.99, rs->out_pool));
}
static PgfExprProb*
pgf_reasoner_next(PgfReasoner* rs)
{
for (;;) {
if (rs->n_reported_exprs < gu_buf_length(rs->exprs)) {
return gu_buf_get(rs->exprs, PgfExprProb*, rs->n_reported_exprs++);
}
if (gu_buf_length(rs->pqueue) == 0)
return NULL;
PgfReasonerState* st;
gu_buf_heap_pop(rs->pqueue, &pgf_expr_state_order, &st);
#ifdef PGF_REASONER_DEBUG
{
GuPool* tmp_pool = gu_new_pool();
GuOut* out = gu_file_out(stderr, tmp_pool);
GuExn* err = gu_exn(tmp_pool);
st->print(rs, st, out, err, tmp_pool);
gu_pool_free(tmp_pool);
}
#endif
rs->eval_gates->enter(rs, &st->header);
}
}
static void
pgf_reasoner_enum_next(GuEnum* self, void* to, GuPool* pool)
{
PgfReasoner* pr = gu_container(self, PgfReasoner, en);
*(PgfExprProb**)to = pgf_reasoner_next(pr);
}
PGF_INTERNAL PgfReasoner*
pgf_new_reasoner(PgfPGF* pgf, GuExn* err, GuPool* pool, GuPool* out_pool)
{
size_t n_cafs =
(pgf->abstract.eval_gates->cafs == NULL)
? 0 : gu_seq_length(pgf->abstract.eval_gates->cafs);
PgfReasoner* rs = gu_new_flex(pool, PgfReasoner, cafs, n_cafs);
rs->pool = pool,
rs->out_pool = out_pool;
rs->err = err;
rs->abstract = &pgf->abstract,
rs->table = gu_new_string_map(PgfAnswers*, &gu_null_struct, rs->pool),
rs->start = NULL;
rs->eval_gates = pgf->abstract.eval_gates;
rs->pqueue = gu_new_buf(PgfReasonerState*, rs->pool);
rs->exprs = gu_new_buf(PgfExprProb*, rs->pool);
rs->n_reported_exprs = 0;
rs->en.next = pgf_reasoner_enum_next;
PgfFunction* cafs = gu_seq_data(rs->eval_gates->cafs);
for (size_t i = 0; i < n_cafs; i++) {
rs->cafs[i].header.code = cafs[i];
rs->cafs[i].val = NULL;
}
return rs;
}
PGF_API PgfExprEnum*
pgf_generate_all(PgfPGF* pgf, PgfType* typ, GuExn* err, GuPool* pool, GuPool* out_pool)
{
PgfReasoner* rs = pgf_new_reasoner(pgf, err, pool, out_pool);
PgfAnswers* answers = gu_new(PgfAnswers, rs->pool);
answers->parents = gu_new_buf(PgfExprState*, rs->pool);
answers->exprs = rs->exprs;
answers->outside_prob = 0;
gu_map_put(rs->table, typ->cid, PgfAnswers*, answers);
PgfAbsCat* abscat = gu_seq_binsearch(rs->abstract->cats, pgf_abscat_order, PgfAbsCat, typ->cid);
if (abscat != NULL) {
rs->start = gu_new(PgfClosure, rs->pool);
rs->start->code = abscat->predicate;
rs->eval_gates->enter(rs, rs->start);
}
return &rs->en;
}

View File

@@ -1,174 +0,0 @@
#ifndef PGF_REASONER_H_
#define PGF_REASONER_H_
typedef GuStringMap PgfAbswersMap;
typedef struct PgfReasoner PgfReasoner;
typedef struct PgfReasonerState PgfReasonerState;
typedef struct PgfExprState PgfExprState;
typedef struct {
PgfFunction code;
} PgfClosure;
typedef struct {
PgfClosure header;
PgfClosure* val;
} PgfIndirection;
typedef struct {
PgfLiteral lit;
GuBuf* consts;
void* enter_stack_ptr;
} PgfEvalAccum;
struct PgfReasoner {
GuPool* pool;
GuPool* out_pool;
PgfAbstr* abstract;
PgfAbswersMap* table;
GuBuf* pqueue;
GuBuf* exprs;
size_t n_reported_exprs;
PgfClosure* start;
PgfEvalGates* eval_gates; // cached from pgf->abstr->eval_gates
GuExn* err;
void* enter_stack_ptr;
void* tmp; // for temporary register spills
PgfExprEnum en;
PgfIndirection cafs[]; // derived from gu_seq_data(pgf->abstr->eval_gates->cafs)
};
typedef struct PgfEnv PgfEnv;
struct PgfEnv {
PgfEnv* next;
PgfClosure* closure;
};
typedef struct {
PgfClosure header;
PgfEnv* env;
PgfExpr expr;
} PgfExprThunk;
typedef struct {
PgfClosure header;
PgfClosure* con;
PgfClosure* args[];
} PgfValue;
typedef struct {
PgfClosure header;
int level;
} PgfValueGen;
typedef struct {
PgfClosure header;
PgfEnv* env;
PgfMetaId id;
} PgfValueMeta;
typedef struct {
PgfClosure header;
PgfLiteral lit;
} PgfValueLit;
typedef struct {
PgfClosure header;
PgfLiteral lit;
GuBuf* consts;
} PgfValueSum;
typedef struct {
PgfClosure header;
PgfClosure* fun;
size_t n_args;
PgfClosure* args[];
} PgfValuePAP;
struct PgfEvalGates {
PgfFunction evaluate_expr_thunk;
PgfFunction evaluate_indirection;
PgfFunction evaluate_value;
PgfFunction evaluate_value_lit;
PgfFunction evaluate_value_pap;
PgfFunction evaluate_value_lambda;
PgfFunction evaluate_value_const;
PgfFunction evaluate_meta;
PgfFunction evaluate_gen;
PgfFunction evaluate_sum;
PgfFunction evaluate_caf;
PgfFunction update_closure;
PgfFunction update_pap;
PgfFunction mk_const;
PgfFunction combine1;
PgfFunction combine2;
PgfFunction complete;
PgfClosure* (*enter)(PgfReasoner* rs, PgfClosure* closure);
GuFinalizer fin;
GuSeq* cafs;
};
PGF_INTERNAL_DECL PgfReasoner*
pgf_new_reasoner(PgfPGF* pgf, GuExn* err, GuPool* pool, GuPool* out_pool);
PGF_INTERNAL_DECL void
pgf_reasoner_try_first(PgfReasoner* rs, PgfExprState* parent, PgfAbsFun* absfun);
PGF_INTERNAL_DECL void
pgf_reasoner_try_else(PgfReasoner* rs, PgfExprState* prev, PgfAbsFun* absfun);
PGF_INTERNAL_DECL void
pgf_reasoner_combine1(PgfReasoner* rs, PgfClosure* closure);
PGF_INTERNAL_DECL void
pgf_reasoner_combine2(PgfReasoner* rs, PgfClosure* closure);
PGF_INTERNAL_DECL void
pgf_reasoner_complete(PgfReasoner* rs, PgfExprState* st);
PGF_INTERNAL_DECL void
pgf_reasoner_try_constant(PgfReasoner* rs, PgfExprState* prev, PgfAbsFun* absfun);
PGF_INTERNAL_DECL void
pgf_reasoner_mk_string(PgfReasoner* rs, PgfExprState* parent);
PGF_INTERNAL_DECL void
pgf_reasoner_mk_int(PgfReasoner* rs, PgfExprState* parent);
PGF_INTERNAL_DECL void
pgf_reasoner_mk_float(PgfReasoner* rs, PgfExprState* parent);
PGF_INTERNAL_DECL PgfClosure*
pgf_evaluate_expr_thunk(PgfReasoner* rs, PgfExprThunk* thunk);
PGF_INTERNAL_DECL PgfClosure*
pgf_evaluate_lambda_application(PgfReasoner* rs, PgfExprThunk* lambda,
PgfClosure* arg);
PGF_INTERNAL_DECL void
pgf_evaluate_accum_init_int(PgfReasoner* rs,
PgfEvalAccum* accum, int val);
PGF_INTERNAL_DECL void
pgf_evaluate_accum_init_str(PgfReasoner* rs,
PgfEvalAccum* accum, GuString val);
PGF_INTERNAL_DECL void
pgf_evaluate_accum_init_flt(PgfReasoner* rs,
PgfEvalAccum* accum, float val);
PGF_INTERNAL_DECL void
pgf_evaluate_accum_add(PgfReasoner* rs,
PgfEvalAccum* accum, PgfClosure* closure);
PGF_INTERNAL_DECL PgfClosure*
pgf_evaluate_accum_done(PgfReasoner* rs, PgfEvalAccum* accum);
#endif

View File

@@ -1,583 +0,0 @@
#include <pgf/data.h>
#include <pgf/expr.h>
#include <pgf/linearizer.h>
#include <gu/utf8.h>
PGF_INTERNAL int
cmp_string(PgfCohortSpot* spot, GuString tok,
bool case_sensitive)
{
for (;;) {
GuUCS c2 = gu_utf8_decode((const uint8_t**) &tok);
if (c2 == 0)
return 0;
const uint8_t* p = (uint8_t*) spot->ptr;
GuUCS c1 = gu_utf8_decode(&p);
if (c1 == 0)
return -1;
if (!case_sensitive) {
c1 = gu_ucs_to_lower(c1);
c2 = gu_ucs_to_lower(c2);
}
if (c1 != c2)
return (c1-c2);
spot->ptr = (GuString) p;
spot->pos++;
}
}
PGF_INTERNAL bool
skip_space(GuString* psent, size_t* ppos)
{
const uint8_t* p = (uint8_t*) *psent;
if (!gu_ucs_is_space(gu_utf8_decode(&p)))
return false;
*psent = (GuString) p;
(*ppos)++;
return true;
}
PGF_INTERNAL int
pgf_symbols_cmp(PgfCohortSpot* spot,
PgfSymbols* syms, size_t* sym_idx,
bool case_sensitive)
{
size_t n_syms = gu_seq_length(syms);
while (*sym_idx < n_syms) {
PgfSymbol sym = gu_seq_get(syms, PgfSymbol, *sym_idx);
if (*sym_idx > 0) {
if (!skip_space(&spot->ptr,&spot->pos)) {
if (*spot->ptr == 0)
return -1;
return 1;
}
while (*spot->ptr != 0) {
if (!skip_space(&spot->ptr,&spot->pos))
break;
}
}
GuVariantInfo inf = gu_variant_open(sym);
switch (inf.tag) {
case PGF_SYMBOL_CAT:
case PGF_SYMBOL_LIT:
case PGF_SYMBOL_VAR: {
if (*spot->ptr == 0)
return -1;
return 1;
}
case PGF_SYMBOL_KS: {
PgfSymbolKS* pks = inf.data;
if (*spot->ptr == 0)
return -1;
int cmp = cmp_string(spot,pks->token, case_sensitive);
if (cmp != 0)
return cmp;
break;
}
case PGF_SYMBOL_KP:
case PGF_SYMBOL_BIND:
case PGF_SYMBOL_NE:
case PGF_SYMBOL_SOFT_BIND:
case PGF_SYMBOL_SOFT_SPACE:
case PGF_SYMBOL_CAPIT:
case PGF_SYMBOL_ALL_CAPIT: {
return -1;
}
default:
gu_impossible();
}
(*sym_idx)++;
}
return 0;
}
static void
pgf_morpho_iter(PgfProductionIdx* idx,
PgfMorphoCallback* callback,
GuExn* err)
{
size_t n_entries = gu_buf_length(idx);
for (size_t i = 0; i < n_entries; i++) {
PgfProductionIdxEntry* entry =
gu_buf_index(idx, PgfProductionIdxEntry, i);
PgfCId lemma = entry->papp->fun->absfun->name;
GuString analysis = entry->ccat->cnccat->labels[entry->lin_idx];
prob_t prob = entry->ccat->cnccat->abscat->prob +
entry->papp->fun->absfun->ep.prob;
callback->callback(callback,
lemma, analysis, prob, err);
if (!gu_ok(err))
return;
}
}
typedef struct {
GuOrder order;
bool case_sensitive;
} PgfSequenceOrder;
PGF_INTERNAL bool
pgf_is_case_sensitive(PgfConcr* concr)
{
PgfFlag* flag =
gu_seq_binsearch(concr->cflags, pgf_flag_order, PgfFlag, "case_sensitive");
if (flag != NULL) {
GuVariantInfo inf = gu_variant_open(flag->value);
if (inf.tag == PGF_LITERAL_STR) {
PgfLiteralStr* lstr = inf.data;
if (strcmp(lstr->val, "off") == 0)
return false;
}
}
return true;
}
static int
pgf_sequence_cmp_fn(GuOrder* order, const void* p1, const void* p2)
{
PgfSequenceOrder* self = gu_container(order, PgfSequenceOrder, order);
PgfCohortSpot spot = {0, (GuString) p1};
const PgfSequence* sp2 = p2;
size_t sym_idx = 0;
int res = pgf_symbols_cmp(&spot, sp2->syms, &sym_idx, self->case_sensitive);
if (res == 0 && (*spot.ptr != 0 || sym_idx != gu_seq_length(sp2->syms))) {
res = 1;
}
return res;
}
PGF_API void
pgf_lookup_morpho(PgfConcr *concr, GuString sentence,
PgfMorphoCallback* callback, GuExn* err)
{
if (concr->sequences == NULL) {
GuExnData* err_data = gu_raise(err, PgfExn);
if (err_data) {
err_data->data = "The concrete syntax is not loaded";
return;
}
}
size_t index = 0;
PgfSequenceOrder order = { { pgf_sequence_cmp_fn },
pgf_is_case_sensitive(concr) };
if (gu_seq_binsearch_index(concr->sequences, &order.order,
PgfSequence, (void*) sentence,
&index)) {
PgfSequence* seq = NULL;
/* If the match is case-insensitive then there might be more
* matches around the current index. We must check the neighbour
* sequences for matching as well.
*/
if (!order.case_sensitive) {
size_t i = index;
while (i > 0) {
seq = gu_seq_index(concr->sequences, PgfSequence, i-1);
size_t sym_idx = 0;
PgfCohortSpot spot = {0, sentence};
if (pgf_symbols_cmp(&spot, seq->syms, &sym_idx, order.case_sensitive) != 0) {
break;
}
if (seq->idx != NULL)
pgf_morpho_iter(seq->idx, callback, err);
i--;
}
}
seq = gu_seq_index(concr->sequences, PgfSequence, index);
if (seq->idx != NULL)
pgf_morpho_iter(seq->idx, callback, err);
if (!order.case_sensitive) {
size_t i = index+1;
while (i < gu_seq_length(concr->sequences)) {
seq = gu_seq_index(concr->sequences, PgfSequence, i);
size_t sym_idx = 0;
PgfCohortSpot spot = {0, sentence};
if (pgf_symbols_cmp(&spot, seq->syms, &sym_idx, order.case_sensitive) != 0) {
break;
}
if (seq->idx != NULL)
pgf_morpho_iter(seq->idx, callback, err);
i++;
}
}
}
}
typedef struct {
GuEnum en;
PgfConcr* concr;
GuString sentence;
size_t len;
PgfMorphoCallback* callback;
GuExn* err;
bool case_sensitive;
GuBuf* spots;
GuBuf* skip_spots;
GuBuf* empty_buf;
GuBuf* found;
} PgfCohortsState;
static int
cmp_cohort_spot(GuOrder* self, const void* a, const void* b)
{
PgfCohortSpot *s1 = (PgfCohortSpot *) a;
PgfCohortSpot *s2 = (PgfCohortSpot *) b;
return (s1->ptr-s2->ptr);
}
static GuOrder
pgf_cohort_spot_order[1] = {{ cmp_cohort_spot }};
static void
pgf_lookup_cohorts_report_skip(PgfCohortsState *state,
PgfCohortSpot* spot)
{
size_t n_spots = gu_buf_length(state->skip_spots);
for (size_t i = 0; i < n_spots; i++) {
PgfCohortSpot* skip_spot =
gu_buf_index(state->skip_spots, PgfCohortSpot, i);
PgfCohortRange* range = gu_buf_insert(state->found, 0);
range->start = *skip_spot;
range->end = *spot;
range->buf = state->empty_buf;
}
gu_buf_flush(state->skip_spots);
}
static void
pgf_lookup_cohorts_helper(PgfCohortsState *state, PgfCohortSpot* spot,
int i, int j, ptrdiff_t min, ptrdiff_t max)
{
// This is a variation of a binary search algorithm which
// can retrieve all prefixes of a string with minimal
// comparisons, i.e. there is no need to lookup every
// prefix separately.
while (i <= j) {
int k = (i+j) / 2;
PgfSequence* seq = gu_seq_index(state->concr->sequences, PgfSequence, k);
PgfCohortSpot current = *spot;
size_t sym_idx = 0;
int cmp = pgf_symbols_cmp(&current, seq->syms, &sym_idx, state->case_sensitive);
if (cmp < 0) {
j = k-1;
} else if (cmp > 0) {
ptrdiff_t len = current.ptr - spot->ptr;
if (min <= len)
pgf_lookup_cohorts_helper(state, spot, i, k-1, min, len);
if (len+1 <= max)
pgf_lookup_cohorts_helper(state, spot, k+1, j, len+1, max);
break;
} else {
ptrdiff_t len = current.ptr - spot->ptr;
if (min <= len)
pgf_lookup_cohorts_helper(state, spot, i, k-1, min, len);
if (seq->idx != NULL && gu_buf_length(seq->idx) > 0) {
// Report unknown words
pgf_lookup_cohorts_report_skip(state, spot);
// Report the actual hit
PgfCohortRange* range = gu_buf_insert(state->found, 0);
range->start = *spot;
range->end = current;
range->buf = seq->idx;
// Schedule the next search spot
while (*current.ptr != 0) {
if (!skip_space(&current.ptr, &current.pos))
break;
}
gu_buf_heap_push(state->spots, pgf_cohort_spot_order, &current);
}
if (len <= max)
pgf_lookup_cohorts_helper(state, spot, k+1, j, len, max);
break;
}
}
}
static void
pgf_lookup_cohorts_enum_next(GuEnum* self, void* to, GuPool* pool)
{
PgfCohortsState* state = gu_container(self, PgfCohortsState, en);
while (gu_buf_length(state->found) == 0 &&
gu_buf_length(state->spots) > 0) {
PgfCohortSpot spot;
gu_buf_heap_pop(state->spots, pgf_cohort_spot_order, &spot);
GuString next_ptr = state->sentence+state->len;
while (gu_buf_length(state->spots) > 0) {
GuString ptr =
gu_buf_index(state->spots, PgfCohortSpot, 0)->ptr;
if (ptr > spot.ptr) {
next_ptr = ptr;
break;
}
gu_buf_heap_pop(state->spots, pgf_cohort_spot_order, &spot);
}
bool needs_report = true;
while (next_ptr > spot.ptr) {
pgf_lookup_cohorts_helper
(state, &spot,
0, gu_seq_length(state->concr->sequences)-1,
1, (state->sentence+state->len)-spot.ptr);
// got a hit -> exit
if (gu_buf_length(state->found) > 0)
break;
if (needs_report) {
// no hit, but the word must be reported as unknown.
gu_buf_push(state->skip_spots, PgfCohortSpot, spot);
needs_report = false;
}
// skip one character
const uint8_t* ptr = (const uint8_t*) spot.ptr;
GuUCS c = gu_utf8_decode(&ptr);
if (gu_ucs_is_space(c)) {
// We have encounter a space and we must report
// a new unknown word.
pgf_lookup_cohorts_report_skip(state, &spot);
spot.ptr = (GuString) ptr;
spot.pos++;
// Schedule the next search spot
while (*spot.ptr != 0) {
if (!skip_space(&spot.ptr, &spot.pos))
break;
}
gu_buf_heap_push(state->spots, pgf_cohort_spot_order, &spot);
break;
} else {
spot.ptr = (GuString) ptr;
spot.pos++;
}
}
}
PgfCohortSpot end_spot = {state->len, state->sentence+state->len};
pgf_lookup_cohorts_report_skip(state, &end_spot);
PgfCohortRange* pRes = (PgfCohortRange*)to;
if (gu_buf_length(state->found) == 0) {
pRes->start.pos = 0;
pRes->start.ptr = NULL;
pRes->end.pos = 0;
pRes->end.ptr = NULL;
pRes->buf = NULL;
} else for (;;) {
*pRes = gu_buf_pop(state->found, PgfCohortRange);
pgf_morpho_iter(pRes->buf, state->callback, state->err);
if (gu_buf_length(state->found) <= 0)
break;
PgfCohortRange* last =
gu_buf_index_last(state->found, PgfCohortRange);
if (last->start.ptr != pRes->start.ptr ||
last->end.ptr != pRes->end.ptr)
break;
}
}
PGF_API GuEnum*
pgf_lookup_cohorts(PgfConcr *concr, GuString sentence,
PgfMorphoCallback* callback,
GuPool* pool, GuExn* err)
{
if (concr->sequences == NULL) {
GuExnData* err_data = gu_raise(err, PgfExn);
if (err_data) {
err_data->data = "The concrete syntax is not loaded";
return NULL;
}
}
PgfCohortsState* state = gu_new(PgfCohortsState, pool);
state->en.next = pgf_lookup_cohorts_enum_next;
state->concr = concr;
state->sentence = sentence;
state->len = strlen(sentence);
state->callback = callback;
state->err = err;
state->case_sensitive= pgf_is_case_sensitive(concr);
state->spots = gu_new_buf(PgfCohortSpot, pool);
state->skip_spots = gu_new_buf(PgfCohortSpot, pool);
state->empty_buf = gu_new_buf(PgfProductionIdxEntry, pool);
state->found = gu_new_buf(PgfCohortRange, pool);
PgfCohortSpot spot = {0,sentence};
while (*spot.ptr != 0) {
if (!skip_space(&spot.ptr, &spot.pos))
break;
}
gu_buf_heap_push(state->spots, pgf_cohort_spot_order, &spot);
return &state->en;
}
typedef struct {
GuEnum en;
PgfSequences* sequences;
GuString prefix;
size_t seq_idx;
bool case_sensitive;
} PgfFullFormState;
struct PgfFullFormEntry {
GuString tokens;
PgfProductionIdx* idx;
};
static void
gu_fullform_enum_next(GuEnum* self, void* to, GuPool* pool)
{
PgfFullFormState* st = gu_container(self, PgfFullFormState, en);
PgfFullFormEntry* entry = NULL;
if (st->sequences != NULL) {
size_t n_seqs = gu_seq_length(st->sequences);
while (st->seq_idx < n_seqs) {
PgfSequence* seq = gu_seq_index(st->sequences, PgfSequence, st->seq_idx);
GuString tokens = pgf_get_tokens(seq->syms, 0, pool);
PgfCohortSpot spot = {0, st->prefix};
if (cmp_string(&spot, tokens, st->case_sensitive) > 0 || *spot.ptr != 0) {
st->seq_idx = n_seqs;
break;
}
if (*tokens != 0 && seq->idx != NULL) {
entry = gu_new(PgfFullFormEntry, pool);
entry->tokens = tokens;
entry->idx = seq->idx;
st->seq_idx++;
break;
}
st->seq_idx++;
}
}
*((PgfFullFormEntry**) to) = entry;
}
PGF_API GuEnum*
pgf_fullform_lexicon(PgfConcr *concr, GuPool* pool)
{
PgfFullFormState* st = gu_new(PgfFullFormState, pool);
st->en.next = gu_fullform_enum_next;
st->sequences = concr->sequences;
st->prefix = "";
st->seq_idx = 0;
st->case_sensitive = true;
return &st->en;
}
PGF_API GuString
pgf_fullform_get_string(PgfFullFormEntry* entry)
{
return entry->tokens;
}
PGF_API void
pgf_fullform_get_analyses(PgfFullFormEntry* entry,
PgfMorphoCallback* callback, GuExn* err)
{
pgf_morpho_iter(entry->idx, callback, err);
}
PGF_API GuEnum*
pgf_lookup_word_prefix(PgfConcr *concr, GuString prefix,
GuPool* pool, GuExn* err)
{
if (concr->sequences == NULL) {
GuExnData* err_data = gu_raise(err, PgfExn);
if (err_data) {
err_data->data = "The concrete syntax is not loaded";
return NULL;
}
}
PgfFullFormState* state = gu_new(PgfFullFormState, pool);
state->en.next = gu_fullform_enum_next;
state->sequences = concr->sequences;
state->prefix = prefix;
state->seq_idx = 0;
state->case_sensitive = pgf_is_case_sensitive(concr);
PgfSequenceOrder order = { { pgf_sequence_cmp_fn },
state->case_sensitive };
if (!gu_seq_binsearch_index(concr->sequences, &order.order,
PgfSequence, (void*) prefix,
&state->seq_idx)) {
state->seq_idx++;
} else if (!state->case_sensitive) {
/* If the match is case-insensitive then there might be more
* matches around the current index. Since we scroll down
* anyway, it is enough to search upwards now.
*/
while (state->seq_idx > 0) {
PgfSequence* seq =
gu_seq_index(concr->sequences, PgfSequence, state->seq_idx-1);
size_t sym_idx = 0;
PgfCohortSpot spot = {0, state->prefix};
if (pgf_symbols_cmp(&spot, seq->syms, &sym_idx, state->case_sensitive) > 0 || *spot.ptr != 0) {
break;
}
state->seq_idx--;
}
}
return &state->en;
}

View File

@@ -1,588 +0,0 @@
#include "pgf.h"
#include "data.h"
#include "gu/mem.h"
#include "gu/string.h"
typedef struct PgfCFHypos PgfCFHypos;
struct PgfCFHypos {
PgfType* ty;
PgfCFHypos* next;
};
typedef struct PgfContext PgfContext;
struct PgfContext {
PgfCId var;
PgfType* ty;
PgfContext* next;
};
typedef struct {
PgfCFHypos* hypos;
PgfCId cat;
} PgfCFType;
typedef struct {
PgfAbstr* abstr;
GuExn* exn;
GuPool* pool;
GuPool* tmp_pool;
PgfMetaId meta_id;
} PgfTypeChecker;
static PgfCFType null_cf_type = { .hypos = NULL, .cat = NULL };
static PgfCFType
pgf_ty2cfty(PgfTypeChecker* checker, PgfType* ty)
{
PgfCFHypos* hypos = NULL;
size_t n_hypos = gu_seq_length(ty->hypos);
while (n_hypos-- > 0) {
PgfHypo* hypo = gu_seq_index(ty->hypos, PgfHypo, n_hypos);
PgfCFHypos* new_hypos = gu_new(PgfCFHypos, checker->tmp_pool);
new_hypos->ty = hypo->type;
new_hypos->next = hypos;
hypos = new_hypos;
}
return ((PgfCFType) { .hypos = hypos, .cat = ty->cid });
}
static PgfType*
pgf_cfty2ty(PgfTypeChecker* checker, PgfCFType cf_ty)
{
PgfCFHypos* hypos;
size_t n_hypos = 0;
hypos = cf_ty.hypos;
while (hypos != NULL) {
n_hypos++;
hypos = hypos->next;
}
PgfType* ty = gu_new(PgfType, checker->pool);
ty->hypos = gu_new_seq(PgfHypo, n_hypos, checker->pool);
ty->cid = cf_ty.cat;
ty->n_exprs = 0;
size_t i = 0;
hypos = cf_ty.hypos;
while (hypos != NULL) {
PgfHypo* hypo = gu_seq_index(ty->hypos, PgfHypo, i++);
hypo->bind_type = PGF_BIND_TYPE_EXPLICIT;
hypo->cid = "_";
hypo->type = pgf_cfty2ty(checker, pgf_ty2cfty(checker, hypos->ty));
hypos = hypos->next;
}
return ty;
}
static PgfPrintContext*
pgf_tc_mk_print_context(PgfTypeChecker* checker, PgfContext* ctxt)
{
PgfPrintContext* pctxt = NULL;
PgfPrintContext** pprev = &pctxt;
while (ctxt != NULL) {
PgfPrintContext* new_pctxt =
gu_new(PgfPrintContext, checker->tmp_pool);
new_pctxt->name = ctxt->var;
new_pctxt->next = NULL;
*pprev = new_pctxt;
pprev = &new_pctxt->next;
ctxt = ctxt->next;
}
return pctxt;
}
static void
pgf_tc_err_cannot_infer(PgfTypeChecker* checker, PgfContext* ctxt, PgfExpr e)
{
GuStringBuf* sbuf = gu_new_string_buf(checker->tmp_pool);
GuOut* out = gu_string_buf_out(sbuf);
GuExn* err = gu_exn(checker->tmp_pool);
gu_puts("Cannot infer the type of expression ", out, err);
pgf_print_expr(e, pgf_tc_mk_print_context(checker, ctxt), 0, out, err);
GuExnData* exn = gu_raise(checker->exn, PgfTypeError);
exn->data = (void*)
gu_string_buf_freeze(sbuf, exn->pool);
}
static void
pgf_tc_err_exp_fun_type_1(PgfTypeChecker* checker, PgfContext* ctxt,
PgfExpr e, PgfType* ty)
{
GuStringBuf* sbuf = gu_new_string_buf(checker->tmp_pool);
GuOut* out = gu_string_buf_out(sbuf);
GuExn* err = gu_exn(checker->tmp_pool);
PgfPrintContext* pctxt = pgf_tc_mk_print_context(checker, ctxt);
gu_puts("The expression ", out, err);
pgf_print_expr(e, pctxt, 0, out, err);
gu_puts(" is of function type but ", out, err);
pgf_print_type(ty, pctxt, 0, out, err);
gu_puts(" is expected", out, err);
GuExnData* exn = gu_raise(checker->exn, PgfTypeError);
exn->data = (void*)
gu_string_buf_freeze(sbuf, exn->pool);
}
static void
pgf_tc_err_exp_fun_type_2(PgfTypeChecker* checker, PgfContext* ctxt,
PgfExpr e, PgfType* ty)
{
GuStringBuf* sbuf = gu_new_string_buf(checker->tmp_pool);
GuOut* out = gu_string_buf_out(sbuf);
GuExn* err = gu_exn(checker->tmp_pool);
PgfPrintContext* pctxt = pgf_tc_mk_print_context(checker, ctxt);
gu_puts("A function type is expected for the expression ", out, err);
pgf_print_expr(e, pctxt, 0, out, err);
gu_puts(" instead of type ", out, err);
pgf_print_type(ty, pctxt, 0, out, err);
GuExnData* exn = gu_raise(checker->exn, PgfTypeError);
exn->data = (void*)
gu_string_buf_freeze(sbuf, exn->pool);
}
static void
pgf_tc_err_n_args(PgfTypeChecker* checker,
PgfAbsCat* abs_cat, size_t n_args)
{
GuExnData* exn = gu_raise(checker->exn, PgfTypeError);
exn->data = (void*)
gu_format_string(exn->pool,
"The category %s has %d indices but %d are given",
abs_cat->name,
gu_seq_length(abs_cat->context),
n_args);
}
static void
pgf_tc_err_type_mismatch(PgfTypeChecker* checker,
PgfContext* ctxt,
PgfExpr e, PgfCFType ty1, PgfCFType ty2)
{
GuStringBuf* sbuf = gu_new_string_buf(checker->tmp_pool);
GuOut* out = gu_string_buf_out(sbuf);
GuExn* err = gu_exn(checker->tmp_pool);
PgfPrintContext* pctxt = pgf_tc_mk_print_context(checker, ctxt);
gu_puts("The expected type of the expression ", out, err);
pgf_print_expr(e, pctxt, 0, out, err);
gu_puts(" is ", out, err);
pgf_print_type(pgf_cfty2ty(checker, ty1), pctxt, 0, out, err);
gu_puts(" but ", out, err);
pgf_print_type(pgf_cfty2ty(checker, ty2), pctxt, 0, out, err);
gu_puts(" is infered", out, err);
GuExnData* exn = gu_raise(checker->exn, PgfTypeError);
exn->data = (void*)
gu_string_buf_freeze(sbuf, exn->pool);
}
static bool
pgf_unify_types(PgfTypeChecker* checker, PgfCFType ty1, PgfCFType ty2)
{
if (strcmp(ty1.cat, ty2.cat) != 0)
return false;
while (ty1.hypos != NULL && ty2.hypos != NULL) {
if (!pgf_unify_types(checker,
pgf_ty2cfty(checker, ty1.hypos->ty),
pgf_ty2cfty(checker, ty2.hypos->ty)))
return false;
ty1.hypos = ty1.hypos->next;
ty2.hypos = ty2.hypos->next;
}
if (ty1.hypos != NULL || ty2.hypos != NULL)
return false;
return true;
}
static PgfCFType
pgf_inf_expr(PgfTypeChecker* checker, PgfContext* ctxt, PgfExpr* pe);
static void
pgf_tc_expr(PgfTypeChecker* checker,
PgfContext* ctxt, PgfExpr* pe, PgfCFType ty)
{
GuVariantInfo i = gu_variant_open(*pe);
switch (i.tag) {
case PGF_EXPR_ABS: {
PgfExprAbs* eabs = i.data;
if (ty.hypos == NULL) {
pgf_tc_err_exp_fun_type_1(checker, ctxt, *pe, pgf_cfty2ty(checker, ty));
return;
}
PgfContext* new_ctxt = gu_new(PgfContext, checker->tmp_pool);
new_ctxt->var = eabs->id;
new_ctxt->ty = ty.hypos->ty;
new_ctxt->next = ctxt;
PgfExprAbs* new_eabs =
gu_new_variant(PGF_EXPR_ABS,
PgfExprAbs,
pe, checker->pool);
new_eabs->bind_type = eabs->bind_type;
new_eabs->id = gu_string_copy(eabs->id, checker->pool);
new_eabs->body = eabs->body;
PgfCFType new_ty = { .hypos = ty.hypos->next, .cat = ty.cat };
pgf_tc_expr(checker, new_ctxt, &new_eabs->body, new_ty);
break;
}
case PGF_EXPR_LIT:
case PGF_EXPR_APP:
case PGF_EXPR_FUN:
case PGF_EXPR_VAR:
case PGF_EXPR_TYPED: {
PgfCFType inf_ty =
pgf_inf_expr(checker, ctxt, pe);
if (!gu_ok(checker->exn))
return;
if (!pgf_unify_types(checker, ty, inf_ty)) {
pgf_tc_err_type_mismatch(checker, ctxt, *pe, ty, inf_ty);
return;
}
break;
}
case PGF_EXPR_META: {
PgfExprMeta* new_emeta =
gu_new_variant(PGF_EXPR_META,
PgfExprMeta,
pe, checker->pool);
new_emeta->id = checker->meta_id++;
break;
}
case PGF_EXPR_IMPL_ARG: {
PgfExprImplArg* eimpl = i.data;
PgfExprImplArg* new_eimpl =
gu_new_variant(PGF_EXPR_IMPL_ARG,
PgfExprImplArg,
pe, checker->pool);
new_eimpl->expr = eimpl->expr;
pgf_tc_expr(checker, ctxt, &new_eimpl->expr, ty);
break;
}
default:
gu_impossible();
}
}
static void
pgf_tc_type(PgfTypeChecker* checker, PgfType** pty)
{
PgfType* ty = *pty;
PgfAbsCat* abs_cat =
gu_seq_binsearch(checker->abstr->cats, pgf_abscat_order, PgfAbsCat, ty->cid);
if (abs_cat == NULL) {
GuExnData* exn = gu_raise(checker->exn, PgfExn);
exn->data = (void*)
gu_format_string(exn->pool,
"Unknown category \"%s\"", ty->cid);
return;
}
PgfContext* ctxt = NULL;
size_t n_hypos = gu_seq_length(ty->hypos);
PgfHypos* new_hypos = gu_new_seq(PgfHypo, n_hypos, checker->pool);
for (size_t i = 0; i < n_hypos; i++) {
PgfHypo* hypo = gu_seq_index(ty->hypos, PgfHypo, i);
PgfHypo* new_hypo = gu_seq_index(new_hypos, PgfHypo, i);
new_hypo->bind_type = hypo->bind_type;
new_hypo->cid = gu_string_copy(hypo->cid, checker->pool);
new_hypo->type = hypo->type;
pgf_tc_type(checker, &new_hypo->type);
if (!gu_ok(checker->exn))
return;
PgfContext* new_ctxt = gu_new(PgfContext, checker->tmp_pool);
new_ctxt->var = hypo->cid;
new_ctxt->ty = hypo->type;
new_ctxt->next = ctxt;
ctxt = new_ctxt;
}
PgfType *new_ty =
gu_new_flex(checker->pool, PgfType, exprs, ty->n_exprs);
new_ty->hypos = new_hypos;
new_ty->cid = gu_string_copy(ty->cid, checker->pool);
new_ty->n_exprs = ty->n_exprs;
if (gu_seq_length(abs_cat->context) != ty->n_exprs) {
pgf_tc_err_n_args(checker, abs_cat, ty->n_exprs);
return;
}
for (size_t i = 0; i < ty->n_exprs; i++) {
PgfHypo* hypo = gu_seq_index(abs_cat->context, PgfHypo, i);
new_ty->exprs[i] = ty->exprs[i];
pgf_tc_expr(checker, ctxt, &new_ty->exprs[i], pgf_ty2cfty(checker, hypo->type));
if (!gu_ok(checker->exn))
return;
}
*pty = new_ty;
}
static PgfCFType
pgf_inf_expr(PgfTypeChecker* checker, PgfContext* ctxt, PgfExpr* pe)
{
GuVariantInfo i = gu_variant_open(*pe);
switch (i.tag) {
case PGF_EXPR_ABS: {
pgf_tc_err_cannot_infer(checker, ctxt, *pe);
return null_cf_type;
}
case PGF_EXPR_APP: {
PgfExprApp* eapp = i.data;
PgfExprApp* new_eapp =
gu_new_variant(PGF_EXPR_APP,
PgfExprApp,
pe, checker->pool);
new_eapp->fun = eapp->fun;
new_eapp->arg = eapp->arg;
PgfCFType fun_ty =
pgf_inf_expr(checker, ctxt, &new_eapp->fun);
if (!gu_ok(checker->exn))
return null_cf_type;
if (fun_ty.hypos == NULL) {
pgf_tc_err_exp_fun_type_2(checker,
ctxt,
eapp->fun, pgf_cfty2ty(checker, fun_ty));
return null_cf_type;
}
pgf_tc_expr(checker, ctxt, &new_eapp->arg, pgf_ty2cfty(checker, fun_ty.hypos->ty));
return ((PgfCFType) { .hypos = fun_ty.hypos->next,
.cat = fun_ty.cat
});
}
case PGF_EXPR_LIT: {
PgfExprLit* elit = i.data;
PgfExprLit* new_elit =
gu_new_variant(PGF_EXPR_LIT,
PgfExprLit,
pe, checker->pool);
GuVariantInfo i = gu_variant_open(elit->lit);
switch (i.tag) {
case PGF_LITERAL_STR: {
PgfLiteralStr* lstr = i.data;
PgfLiteralStr* new_lstr =
gu_new_flex_variant(PGF_LITERAL_STR,
PgfLiteralStr,
val, strlen(lstr->val)+1,
&new_elit->lit, checker->pool);
strcpy(new_lstr->val, lstr->val);
return ((PgfCFType) { .hypos = NULL, .cat = "String" });
}
case PGF_LITERAL_INT: {
PgfLiteralInt* lint = i.data;
PgfLiteralInt* new_lint =
gu_new_variant(PGF_LITERAL_INT,
PgfLiteralInt,
&new_elit->lit, checker->pool);
new_lint->val = lint->val;
return ((PgfCFType) { .hypos = NULL, .cat = "Int" });
}
case PGF_LITERAL_FLT: {
PgfLiteralFlt* lflt = i.data;
PgfLiteralFlt* new_lflt =
gu_new_variant(PGF_LITERAL_FLT,
PgfLiteralFlt,
&new_elit->lit, checker->pool);
new_lflt->val = lflt->val;
return ((PgfCFType) { .hypos = NULL, .cat = "Float" });
}
default:
gu_impossible();
}
break;
}
case PGF_EXPR_META: {
pgf_tc_err_cannot_infer(checker, ctxt, *pe);
return null_cf_type;
}
case PGF_EXPR_FUN: {
PgfExprFun* efun = i.data;
PgfType* ty = NULL;
int var = 0;
PgfContext* var_ctxt = ctxt;
while (var_ctxt != NULL) {
if (strcmp(var_ctxt->var, efun->fun) == 0) {
PgfExprVar* new_evar =
gu_new_variant(PGF_EXPR_VAR,
PgfExprVar,
pe, checker->pool);
new_evar->var = var;
ty = var_ctxt->ty;
break;
}
var++;
var_ctxt = var_ctxt->next;
}
if (ty == NULL) {
PgfAbsFun* abs_fun =
gu_seq_binsearch(checker->abstr->funs, pgf_absfun_order, PgfAbsFun, efun->fun);
if (abs_fun == NULL) {
GuExnData* exn = gu_raise(checker->exn, PgfExn);
exn->data = (void*)
gu_format_string(exn->pool,
"Unknown function \"%s\"", efun->fun);
return null_cf_type;
} else {
PgfExprFun *new_efun =
gu_new_flex_variant(PGF_EXPR_FUN,
PgfExprFun,
fun, strlen(efun->fun)+1,
pe, checker->pool);
strcpy(new_efun->fun, efun->fun);
ty = abs_fun->type;
}
}
return pgf_ty2cfty(checker, ty);
}
case PGF_EXPR_VAR: {
PgfExprVar* evar = i.data;
int var = evar->var;
PgfContext* var_ctxt = ctxt;
assert(var_ctxt != NULL);
while (var > 0) {
var--;
var_ctxt = var_ctxt->next;
assert(var_ctxt != NULL);
}
return pgf_ty2cfty(checker, var_ctxt->ty);
}
case PGF_EXPR_TYPED: {
PgfExprTyped* etyped = i.data;
PgfExprTyped* new_etyped =
gu_new_variant(PGF_EXPR_TYPED,
PgfExprTyped,
pe, checker->pool);
new_etyped->expr = etyped->expr;
new_etyped->type = etyped->type;
pgf_tc_type(checker, &new_etyped->type);
if (!gu_ok(checker->exn))
return null_cf_type;
PgfCFType cf_ty = pgf_ty2cfty(checker, new_etyped->type);
pgf_tc_expr(checker, ctxt, &new_etyped->expr, cf_ty);
return cf_ty;
}
case PGF_EXPR_IMPL_ARG: {
PgfExprImplArg* eimpl = i.data;
PgfExprImplArg* new_eimpl =
gu_new_variant(PGF_EXPR_IMPL_ARG,
PgfExprImplArg,
pe, checker->pool);
new_eimpl->expr = eimpl->expr;
return pgf_inf_expr(checker, ctxt, &new_eimpl->expr);
}
default:
gu_impossible();
}
return null_cf_type;
}
PGF_API void
pgf_check_expr(PgfPGF* gr, PgfExpr* pe, PgfType* ty,
GuExn* exn, GuPool* pool)
{
GuPool* tmp_pool = gu_new_pool();
PgfTypeChecker* checker = gu_new(PgfTypeChecker, tmp_pool);
checker->abstr = &gr->abstract;
checker->exn = exn;
checker->pool = pool;
checker->tmp_pool = tmp_pool;
checker->meta_id = 1;
pgf_tc_expr(checker, NULL, pe, pgf_ty2cfty(checker, ty));
gu_pool_free(tmp_pool);
}
PGF_API PgfType*
pgf_infer_expr(PgfPGF* gr, PgfExpr* pe,
GuExn* exn, GuPool* pool)
{
GuPool* tmp_pool = gu_new_pool();
PgfTypeChecker* checker = gu_new(PgfTypeChecker, tmp_pool);
checker->abstr = &gr->abstract;
checker->exn = exn;
checker->pool = pool;
checker->tmp_pool = tmp_pool;
checker->meta_id = 1;
PgfCFType cf_ty = pgf_inf_expr(checker, NULL, pe);
PgfType* ty = NULL;
if (gu_ok(exn)) {
ty = pgf_cfty2ty(checker, cf_ty);
}
gu_pool_free(tmp_pool);
return ty;
}
PGF_API void
pgf_check_type(PgfPGF* gr, PgfType** pty,
GuExn* exn, GuPool* pool)
{
GuPool* tmp_pool = gu_new_pool();
PgfTypeChecker* checker = gu_new(PgfTypeChecker, tmp_pool);
checker->abstr = &gr->abstract;
checker->exn = exn;
checker->pool = pool;
checker->tmp_pool = tmp_pool;
checker->meta_id = 1;
pgf_tc_type(checker, pty);
gu_pool_free(tmp_pool);
}

View File

@@ -1,913 +0,0 @@
#include "data.h"
#include "expr.h"
#include "writer.h"
#include <gu/defs.h>
#include <gu/map.h>
#include <gu/seq.h>
#include <gu/assert.h>
#include <gu/in.h>
#include <gu/bits.h>
#include <gu/exn.h>
#include <gu/utf8.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(__MINGW32__) || defined(_MSC_VER)
#include <malloc.h>
#endif
//
// PgfWriter
//
struct PgfWriter {
GuOut* out;
GuExn* err;
};
PGF_INTERNAL void
pgf_write_tag(uint8_t tag, PgfWriter* wtr)
{
gu_out_u8(wtr->out, tag, wtr->err);
}
PGF_INTERNAL void
pgf_write_uint(uint32_t val, PgfWriter* wtr)
{
for (;;) {
uint8_t b = val & 0x7F;
val = val >> 7;
if (val == 0) {
gu_out_u8(wtr->out, b, wtr->err);
break;
} else {
gu_out_u8(wtr->out, b | 0x80, wtr->err);
gu_return_on_exn(wtr->err, );
}
}
}
PGF_INTERNAL void
pgf_write_int(int32_t val, PgfWriter* wtr)
{
pgf_write_uint((uint32_t) val, wtr);
}
PGF_INTERNAL void
pgf_write_len(size_t len, PgfWriter* wtr)
{
pgf_write_int(len, wtr);
}
PGF_INTERNAL void
pgf_write_cid(PgfCId id, PgfWriter* wtr)
{
size_t len = strlen(id);
pgf_write_len(len, wtr);
gu_return_on_exn(wtr->err, );
gu_out_bytes(wtr->out, (uint8_t*) id, len, wtr->err);
}
PGF_INTERNAL void
pgf_write_string(GuString val, PgfWriter* wtr)
{
size_t len = 0;
const uint8_t* buf = (const uint8_t*) val;
const uint8_t* p = buf;
while (gu_utf8_decode(&p) != 0)
len++;
pgf_write_len(len, wtr);
gu_return_on_exn(wtr->err, );
gu_out_bytes(wtr->out, (uint8_t*) val, (p-buf)-1, wtr->err);
}
PGF_INTERNAL void
pgf_write_double(double val, PgfWriter* wtr)
{
gu_out_f64be(wtr->out, val, wtr->err);
}
static void
pgf_write_literal(PgfLiteral lit, PgfWriter* wtr)
{
GuVariantInfo i = gu_variant_open(lit);
pgf_write_tag(i.tag, wtr);
gu_return_on_exn(wtr->err, );
switch (i.tag) {
case PGF_LITERAL_STR: {
PgfLiteralStr *lstr = i.data;
pgf_write_string(lstr->val, wtr);
break;
}
case PGF_LITERAL_INT: {
PgfLiteralInt *lint = i.data;
pgf_write_int(lint->val, wtr);
break;
}
case PGF_LITERAL_FLT: {
PgfLiteralFlt *lflt = i.data;
pgf_write_double(lflt->val, wtr);
break;
}
default:
gu_impossible();
}
}
static void
pgf_write_flags(PgfFlags* flags, PgfWriter* wtr)
{
size_t n_flags = gu_seq_length(flags);
pgf_write_len(n_flags, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < n_flags; i++) {
PgfFlag* flag = gu_seq_index(flags, PgfFlag, i);
pgf_write_cid(flag->name, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_literal(flag->value, wtr);
gu_return_on_exn(wtr->err, );
}
}
static void
pgf_write_type_(PgfType* type, PgfWriter* wtr);
static void
pgf_write_expr_(PgfExpr expr, PgfWriter* wtr)
{
GuVariantInfo i = gu_variant_open(expr);
pgf_write_tag(i.tag, wtr);
gu_return_on_exn(wtr->err, );
switch (i.tag) {
case PGF_EXPR_ABS:{
PgfExprAbs *eabs = i.data;
pgf_write_tag(eabs->bind_type, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_cid(eabs->id, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_expr_(eabs->body, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_EXPR_APP: {
PgfExprApp *eapp = i.data;
pgf_write_expr_(eapp->fun, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_expr_(eapp->arg, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_EXPR_LIT: {
PgfExprLit *elit = i.data;
pgf_write_literal(elit->lit, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_EXPR_META: {
PgfExprMeta *emeta = i.data;
pgf_write_int(emeta->id, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_EXPR_FUN: {
PgfExprFun *efun = i.data;
pgf_write_cid(efun->fun, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_EXPR_VAR: {
PgfExprVar *evar = i.data;
pgf_write_int(evar->var, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_EXPR_TYPED: {
PgfExprTyped *etyped = i.data;
pgf_write_expr_(etyped->expr, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_type_(etyped->type, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_EXPR_IMPL_ARG: {
PgfExprImplArg *eimpl = i.data;
pgf_write_expr_(eimpl->expr, wtr);
gu_return_on_exn(wtr->err, );
break;
}
default:
gu_impossible();
}
}
static void
pgf_write_hypo(PgfHypo* hypo, PgfWriter* wtr)
{
pgf_write_tag(hypo->bind_type, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_cid(hypo->cid, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_type_(hypo->type, wtr);
gu_return_on_exn(wtr->err, );
}
static void
pgf_write_type_(PgfType* type, PgfWriter* wtr)
{
size_t n_hypos = gu_seq_length(type->hypos);
pgf_write_len(n_hypos, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < n_hypos; i++) {
PgfHypo* hypo = gu_seq_index(type->hypos, PgfHypo, i);
pgf_write_hypo(hypo, wtr);
gu_return_on_exn(wtr->err, );
}
pgf_write_cid(type->cid, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_len(type->n_exprs, wtr);
for (size_t i = 0; i < type->n_exprs; i++) {
pgf_write_expr_(type->exprs[i], wtr);
gu_return_on_exn(wtr->err, );
}
}
static void
pgf_write_patt(PgfPatt patt, PgfWriter* wtr)
{
GuVariantInfo i = gu_variant_open(patt);
switch (i.tag) {
case PGF_PATT_APP: {
PgfPattApp *papp = i.data;
pgf_write_cid(papp->ctor, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_len(papp->n_args, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < papp->n_args; i++) {
pgf_write_patt(papp->args[i], wtr);
gu_return_on_exn(wtr->err, );
}
break;
}
case PGF_PATT_VAR: {
PgfPattVar *papp = i.data;
pgf_write_cid(papp->var, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_PATT_AS: {
PgfPattAs *pas = i.data;
pgf_write_cid(pas->var, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_patt(pas->patt, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_PATT_WILD: {
PgfPattWild* pwild = i.data;
((void) pwild);
break;
}
case PGF_PATT_LIT: {
PgfPattLit *plit = i.data;
pgf_write_literal(plit->lit, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_PATT_IMPL_ARG: {
PgfPattImplArg *pimpl = i.data;
pgf_write_patt(pimpl->patt, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_PATT_TILDE: {
PgfPattTilde *ptilde = i.data;
pgf_write_expr_(ptilde->expr, wtr);
gu_return_on_exn(wtr->err, );
break;
}
default:
gu_impossible();
}
}
static void
pgf_write_absfun(PgfAbsFun* absfun, PgfWriter* wtr)
{
pgf_write_cid(absfun->name,wtr);
gu_return_on_exn(wtr->err, );
pgf_write_type_(absfun->type, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_int(absfun->arity, wtr);
pgf_write_tag((absfun->defns == NULL) ? 0 : 1, wtr);
gu_return_on_exn(wtr->err, );
if (absfun->defns != NULL) {
size_t length = gu_seq_length(absfun->defns);
pgf_write_len(length, wtr);
gu_return_on_exn(wtr->err, );
PgfEquation** data = gu_seq_data(absfun->defns);
for (size_t i = 0; i < length; i++) {
PgfEquation *equ = data[i];
pgf_write_len(equ->n_patts, wtr);
gu_return_on_exn(wtr->err, );
for (size_t j = 0; j < equ->n_patts; j++) {
pgf_write_patt(equ->patts[j], wtr);
gu_return_on_exn(wtr->err, );
}
pgf_write_expr_(equ->body, wtr);
gu_return_on_exn(wtr->err, );
}
}
pgf_write_double(exp(-absfun->ep.prob), wtr);
}
static void
pgf_write_absfuns(PgfAbsFuns* absfuns, PgfWriter* wtr)
{
size_t n_funs = gu_seq_length(absfuns);
pgf_write_len(n_funs, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < n_funs; i++) {
PgfAbsFun* absfun = gu_seq_index(absfuns, PgfAbsFun, i);
pgf_write_absfun(absfun, wtr);
gu_return_on_exn(wtr->err, );
}
}
static void
pgf_write_abscat(PgfAbsCat* abscat, PgfAbstr* abstr, PgfWriter* wtr)
{
pgf_write_cid(abscat->name, wtr);
gu_return_on_exn(wtr->err, );
size_t n_hypos = gu_seq_length(abscat->context);
pgf_write_len(n_hypos, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < n_hypos; i++) {
PgfHypo* hypo = gu_seq_index(abscat->context, PgfHypo, i);
pgf_write_hypo(hypo, wtr);
gu_return_on_exn(wtr->err, );
}
size_t n_count = 0;
size_t n_funs = gu_seq_length(abstr->funs);
for (size_t i = 0; i < n_funs; i++) {
PgfAbsFun* fun = gu_seq_index(abstr->funs, PgfAbsFun, i);
if (strcmp(fun->type->cid, abscat->name) == 0) {
n_count++;
}
}
pgf_write_len(n_count, wtr);
for (size_t i = 0; i < n_funs; i++) {
PgfAbsFun* fun = gu_seq_index(abstr->funs, PgfAbsFun, i);
if (strcmp(fun->type->cid, abscat->name) == 0) {
gu_out_f64be(wtr->out, exp(-fun->ep.prob), wtr->err); // ignore
gu_return_on_exn(wtr->err, );
pgf_write_cid(fun->name, wtr);
gu_return_on_exn(wtr->err, );
}
}
pgf_write_double(exp(-abscat->prob), wtr);
}
static void
pgf_write_abscats(PgfAbsCats* abscats, PgfAbstr* abstr, PgfWriter* wtr)
{
size_t n_cats = gu_seq_length(abscats);
pgf_write_len(n_cats, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < n_cats; i++) {
PgfAbsCat* abscat = gu_seq_index(abscats, PgfAbsCat, i);
pgf_write_abscat(abscat, abstr, wtr);
gu_return_on_exn(wtr->err, );
}
}
static void
pgf_write_abstract(PgfAbstr* abstr, PgfWriter* wtr)
{
pgf_write_cid(abstr->name, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_flags(abstr->aflags, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_absfuns(abstr->funs, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_abscats(abstr->cats, abstr, wtr);
gu_return_on_exn(wtr->err, );
}
typedef struct {
GuMapItor itor;
PgfWriter* wtr;
} PgfWriterIter;
static void
pgf_write_printname(GuMapItor* self, const void* key, void* value, GuExn *err)
{
PgfWriterIter* itor = gu_container(self, PgfWriterIter, itor);
PgfCId id = key;
GuString name = value;
pgf_write_cid(id, itor->wtr);
gu_return_on_exn(err, );
pgf_write_string(name, itor->wtr);
gu_return_on_exn(err, );
}
static void
pgf_write_printnames(PgfCIdMap* printnames, PgfWriter* wtr)
{
pgf_write_len(gu_map_count(printnames), wtr);
gu_return_on_exn(wtr->err, );
PgfWriterIter itor;
itor.itor.fn = pgf_write_printname;
itor.wtr = wtr;
gu_map_iter(printnames, &itor.itor, wtr->err);
gu_return_on_exn(wtr->err, );
}
static void
pgf_write_symbols(PgfSymbols*, PgfWriter* wtr);
static void
pgf_write_alternative(PgfAlternative* alt, PgfWriter* wtr)
{
pgf_write_symbols(alt->form, wtr);
gu_return_on_exn(wtr->err,);
size_t n_prefixes = gu_seq_length(alt->prefixes);
pgf_write_len(n_prefixes, wtr);
gu_return_on_exn(wtr->err,);
for (size_t i = 0; i < n_prefixes; i++) {
GuString prefix = gu_seq_get(alt->prefixes, GuString, i);
pgf_write_string(prefix, wtr);
gu_return_on_exn(wtr->err,);
}
}
static void
pgf_write_symbol(PgfSymbol sym, PgfWriter* wtr)
{
GuVariantInfo i = gu_variant_open(sym);
pgf_write_tag(i.tag, wtr);
switch (i.tag) {
case PGF_SYMBOL_CAT: {
PgfSymbolCat *sym_cat = i.data;
pgf_write_int(sym_cat->d, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_int(sym_cat->r, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_SYMBOL_LIT: {
PgfSymbolLit *sym_lit = i.data;
pgf_write_int(sym_lit->d, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_int(sym_lit->r, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_SYMBOL_VAR: {
PgfSymbolVar *sym_var = i.data;
pgf_write_int(sym_var->d, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_int(sym_var->r, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_SYMBOL_KS: {
PgfSymbolKS *sym_ks = i.data;
pgf_write_string(sym_ks->token, wtr);
break;
}
case PGF_SYMBOL_KP: {
PgfSymbolKP *sym_kp = i.data;
pgf_write_symbols(sym_kp->default_form, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_len(sym_kp->n_forms, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < sym_kp->n_forms; i++) {
pgf_write_alternative(&sym_kp->forms[i], wtr);
gu_return_on_exn(wtr->err, );
}
break;
}
case PGF_SYMBOL_NE:
case PGF_SYMBOL_BIND:
case PGF_SYMBOL_SOFT_BIND:
case PGF_SYMBOL_SOFT_SPACE:
case PGF_SYMBOL_CAPIT:
case PGF_SYMBOL_ALL_CAPIT: {
break;
}
default:
gu_impossible();
}
}
static void
pgf_write_symbols(PgfSymbols* syms, PgfWriter* wtr)
{
size_t len = gu_seq_length(syms);
pgf_write_len(len, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < len; i++) {
PgfSymbol sym = gu_seq_get(syms, PgfSymbol, i);
pgf_write_symbol(sym, wtr);
gu_return_on_exn(wtr->err, );
}
}
static void
pgf_write_sequences(PgfSequences* seqs, PgfWriter* wtr)
{
size_t len = gu_seq_length(seqs);
pgf_write_len(len, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < len; i++) {
PgfSymbols* syms = gu_seq_index(seqs, PgfSequence, i)->syms;
pgf_write_symbols(syms, wtr);
gu_return_on_exn(wtr->err, );
}
}
static void
pgf_write_cncfun(PgfCncFun* cncfun, PgfConcr* concr, PgfWriter* wtr)
{
pgf_write_cid(cncfun->absfun->name, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_len(cncfun->n_lins, wtr);
gu_return_on_exn(wtr->err, );
PgfSequence* data = gu_seq_data(concr->sequences);
for (size_t i = 0; i < cncfun->n_lins; i++) {
size_t seq_id = (cncfun->lins[i] - data);
pgf_write_int(seq_id, wtr);
gu_return_on_exn(wtr->err, );
}
}
static void
pgf_write_cncfuns(PgfCncFuns* cncfuns, PgfConcr* concr, PgfWriter* wtr)
{
size_t len = gu_seq_length(cncfuns);
pgf_write_len(len, wtr);
gu_return_on_exn(wtr->err, );
for (size_t funid = 0; funid < len; funid++) {
PgfCncFun* cncfun = gu_seq_get(cncfuns, PgfCncFun*, funid);
pgf_write_cncfun(cncfun, concr, wtr);
gu_return_on_exn(wtr->err, );
}
}
static void
pgf_write_fid(PgfCCat* ccat, PgfWriter* wtr)
{
pgf_write_int(ccat->fid, wtr);
gu_return_on_exn(wtr->err, );
}
static void
pgf_write_funid(PgfCncFun* cncfun, PgfWriter* wtr)
{
pgf_write_int(cncfun->funid, wtr);
gu_return_on_exn(wtr->err, );
}
typedef struct {
GuMapItor itor;
PgfWriter* wtr;
bool do_count;
bool do_defs;
size_t count;
} PgfLinDefRefIter;
static void
pgf_write_ccat_lindefrefs(GuMapItor* self, const void* key, void* value, GuExn *err)
{
PgfLinDefRefIter* itor = gu_container(self, PgfLinDefRefIter, itor);
PgfCCat* ccat = *((PgfCCat**) value);
PgfCncFuns* funs = (itor->do_defs) ? ccat->lindefs : ccat->linrefs;
if (funs != NULL) {
if (itor->do_count) {
itor->count++;
} else {
pgf_write_fid(ccat, itor->wtr);
gu_return_on_exn(err, );
size_t n_funs = gu_seq_length(funs);
pgf_write_len(n_funs, itor->wtr);
gu_return_on_exn(err, );
for (size_t j = 0; j < n_funs; j++) {
PgfCncFun* fun = gu_seq_get(funs, PgfCncFun*, j);
pgf_write_funid(fun, itor->wtr);
}
}
}
}
static void
pgf_write_lindefs(PgfWriter* wtr, PgfConcr* concr)
{
PgfLinDefRefIter itor;
itor.itor.fn = pgf_write_ccat_lindefrefs;
itor.wtr = wtr;
itor.do_count= true;
itor.do_defs = true;
itor.count = 0;
gu_map_iter(concr->ccats, &itor.itor, wtr->err);
pgf_write_len(itor.count, wtr);
gu_return_on_exn(wtr->err, );
itor.do_count = false;
gu_map_iter(concr->ccats, &itor.itor, wtr->err);
gu_return_on_exn(wtr->err, );
}
static void
pgf_write_linrefs(PgfWriter* wtr, PgfConcr* concr)
{
PgfLinDefRefIter itor;
itor.itor.fn = pgf_write_ccat_lindefrefs;
itor.wtr = wtr;
itor.do_count= true;
itor.do_defs = false;
itor.count = 0;
gu_map_iter(concr->ccats, &itor.itor, wtr->err);
pgf_write_len(itor.count, wtr);
gu_return_on_exn(wtr->err, );
itor.do_count = false;
gu_map_iter(concr->ccats, &itor.itor, wtr->err);
gu_return_on_exn(wtr->err, );
}
static void
pgf_write_parg(PgfPArg* parg, PgfWriter* wtr)
{
size_t n_hoas = gu_seq_length(parg->hypos);
pgf_write_len(n_hoas, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < n_hoas; i++) {
PgfCCat* ccat = gu_seq_get(parg->hypos, PgfCCat*, i);
pgf_write_fid(ccat, wtr);
gu_return_on_exn(wtr->err, );
}
pgf_write_fid(parg->ccat, wtr);
gu_return_on_exn(wtr->err, );
}
static void
pgf_write_pargs(PgfPArgs* pargs, PgfWriter* wtr)
{
size_t len = gu_seq_length(pargs);
pgf_write_len(len, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < len; i++) {
PgfPArg* parg = gu_seq_index(pargs, PgfPArg, i);
pgf_write_parg(parg, wtr);
}
}
static void
pgf_write_production(PgfProduction prod, PgfWriter* wtr)
{
GuVariantInfo i = gu_variant_open(prod);
pgf_write_tag(i.tag, wtr);
switch (i.tag) {
case PGF_PRODUCTION_APPLY: {
PgfProductionApply *papp = i.data;
pgf_write_funid(papp->fun, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_pargs(papp->args, wtr);
gu_return_on_exn(wtr->err, );
break;
}
case PGF_PRODUCTION_COERCE: {
PgfProductionCoerce *pcoerce = i.data;
pgf_write_fid(pcoerce->coerce, wtr);
gu_return_on_exn(wtr->err, );
break;
}
default:
gu_impossible();
}
}
static void
pgf_write_ccat(GuMapItor* self, const void* key, void* value, GuExn *err)
{
PgfWriterIter* itor = gu_container(self, PgfWriterIter, itor);
PgfCCat* ccat = *((PgfCCat**) value);
pgf_write_fid(ccat, itor->wtr);
gu_return_on_exn(err, );
size_t n_prods = ccat->prods ? gu_seq_length(ccat->prods) : 0;
pgf_write_len(n_prods, itor->wtr);
gu_return_on_exn(err, );
for (size_t i = 0; i < n_prods; i++) {
PgfProduction prod = gu_seq_get(ccat->prods, PgfProduction, i);
pgf_write_production(prod, itor->wtr);
gu_return_on_exn(err, );
}
}
static void
pgf_write_ccats(GuMap* ccats, PgfWriter* wtr)
{
pgf_write_len(gu_map_count(ccats), wtr);
gu_return_on_exn(wtr->err, );
PgfWriterIter itor;
itor.itor.fn = pgf_write_ccat;
itor.wtr = wtr;
gu_map_iter(ccats, &itor.itor, wtr->err);
}
static void
pgf_write_cnccat(PgfCncCat* cnccat, PgfWriter* wtr)
{
size_t len = gu_seq_length(cnccat->cats);
PgfCCat* first = gu_seq_get(cnccat->cats, PgfCCat*, 0);
PgfCCat* last = gu_seq_get(cnccat->cats, PgfCCat*, len-1);
pgf_write_fid(first,wtr);
pgf_write_fid(last,wtr);
pgf_write_len(cnccat->n_lins, wtr);
for (size_t i = 0; i < cnccat->n_lins; i++) {
pgf_write_string(cnccat->labels[i], wtr);
}
}
static void
pgf_write_cnccat_iter(GuMapItor* self, const void* key, void* value, GuExn *err)
{
PgfWriterIter* itor = gu_container(self, PgfWriterIter, itor);
PgfCncCat* cnccat = *((PgfCncCat**) value);
pgf_write_cid(cnccat->abscat->name, itor->wtr);
gu_return_on_exn(err, );
pgf_write_cnccat(cnccat, itor->wtr);
}
static void
pgf_write_cnccats(PgfCIdMap* cnccats, PgfWriter* wtr)
{
pgf_write_len(gu_map_count(cnccats), wtr);
gu_return_on_exn(wtr->err, );
PgfWriterIter itor;
itor.itor.fn = pgf_write_cnccat_iter;
itor.wtr = wtr;
gu_map_iter(cnccats, &itor.itor, wtr->err);
}
static void
pgf_write_concrete_content(PgfConcr* concr, PgfWriter* wtr)
{
pgf_write_printnames(concr->printnames, wtr);
gu_return_on_exn(wtr->err,);
pgf_write_sequences(concr->sequences, wtr);
gu_return_on_exn(wtr->err,);
pgf_write_cncfuns(concr->cncfuns, concr, wtr);
gu_return_on_exn(wtr->err,);
pgf_write_lindefs(wtr, concr);
pgf_write_linrefs(wtr, concr);
pgf_write_ccats(concr->ccats, wtr);
pgf_write_cnccats(concr->cnccats, wtr);
pgf_write_int(concr->total_cats, wtr);
}
PGF_INTERNAL void
pgf_write_concrete(PgfConcr* concr, PgfWriter* wtr, bool with_content)
{
if (with_content &&
(concr->sequences == NULL || concr->cncfuns == NULL ||
concr->ccats == NULL || concr->cnccats == NULL)) {
// the syntax is not loaded so we must skip it.
return;
}
pgf_write_cid(concr->name, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_flags(concr->cflags, wtr);
gu_return_on_exn(wtr->err, );
if (with_content) {
pgf_write_concrete_content(concr, wtr);
}
gu_return_on_exn(wtr->err, );
}
static void
pgf_write_concretes(size_t n_concrs, PgfConcr** concrs, PgfWriter* wtr, bool with_content)
{
pgf_write_len(n_concrs, wtr);
gu_return_on_exn(wtr->err, );
for (size_t i = 0; i < n_concrs; i++) {
pgf_write_concrete(concrs[i], wtr, with_content);
gu_return_on_exn(wtr->err, );
}
}
PGF_INTERNAL void
pgf_write_pgf(PgfPGF* pgf, size_t n_concrs, PgfConcr** concrs, PgfWriter* wtr) {
gu_out_u16be(wtr->out, pgf->major_version, wtr->err);
gu_return_on_exn(wtr->err, );
gu_out_u16be(wtr->out, pgf->minor_version, wtr->err);
gu_return_on_exn(wtr->err, );
pgf_write_flags(pgf->gflags, wtr);
gu_return_on_exn(wtr->err, );
pgf_write_abstract(&pgf->abstract, wtr);
gu_return_on_exn(wtr->err, );
bool with_content =
(gu_seq_binsearch(pgf->gflags, pgf_flag_order, PgfFlag, "split") == NULL);
pgf_write_concretes(n_concrs, concrs, wtr, with_content);
gu_return_on_exn(wtr->err, );
}
PGF_INTERNAL PgfWriter*
pgf_new_writer(GuOut* out, GuPool* pool, GuExn* err)
{
PgfWriter* wtr = gu_new(PgfWriter, pool);
wtr->out = out;
wtr->err = err;
return wtr;
}

View File

@@ -1,42 +0,0 @@
#ifndef WRITER_H_
#define WRITER_H_
#include <gu/exn.h>
#include <gu/mem.h>
#include <gu/in.h>
// the writer interface
typedef struct PgfWriter PgfWriter;
PGF_INTERNAL_DECL PgfWriter*
pgf_new_writer(GuOut* out, GuPool* pool, GuExn* err);
PGF_INTERNAL_DECL void
pgf_write_tag(uint8_t tag, PgfWriter* wtr);
PGF_INTERNAL_DECL void
pgf_write_uint(uint32_t val, PgfWriter* wtr);
PGF_INTERNAL_DECL void
pgf_write_int(int32_t val, PgfWriter* wtr);
PGF_INTERNAL_DECL void
pgf_write_string(GuString val, PgfWriter* wtr);
PGF_INTERNAL_DECL void
pgf_write_double(double val, PgfWriter* wtr);
PGF_INTERNAL_DECL void
pgf_write_len(size_t len, PgfWriter* wtr);
PGF_INTERNAL_DECL void
pgf_write_cid(PgfCId id, PgfWriter* wtr);
PGF_INTERNAL void
pgf_write_concrete(PgfConcr* concr, PgfWriter* wtr, bool with_content);
PGF_INTERNAL_DECL void
pgf_write_pgf(PgfPGF* pgf, size_t n_concrs, PgfConcr** concrs, PgfWriter* wtr);
#endif // WRITER_H_