tcg-dyngen.c revision 88cc6bfb70dbd23172f00ed679d5f1df8e9d7f53
/*
* Tiny Code Generator for QEMU
*
* Copyright (c) 2008 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef VBOX
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#else
#include <stdio.h>
#include "osdep.h"
#endif
#include "config.h"
#include "osdep.h"
#include "tcg.h"
void __op_gen_label1(){}
void __op_gen_label2(){}
void __op_gen_label3(){}
#else
#endif
#if 0
#if defined(__s390__)
{
}
{
start += 32;
}
asm volatile (";;sync.i;;srlz.i;;");
}
#elif defined(__powerpc__)
{
unsigned long p;
asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
}
asm volatile ("sync" : : : "memory");
asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
}
asm volatile ("sync" : : : "memory");
asm volatile ("isync" : : : "memory");
}
{
asm ("imb");
}
{
unsigned long p;
for (; p < stop; p += 8)
}
{
}
# include <asm/cachectl.h>
{
}
#include <sys/cachectl.h>
{
}
#else
#endif
#ifdef __alpha__
register int gp asm("$29");
static inline void immediate_ldah(void *p, int val) {
*dest &= ~0xffff;
}
}
}
#endif /* __alpha__ */
#ifdef __ia64
/* Patch instruction with "val" where "mask" has 1 bits. */
{
unsigned long shift;
if (shift >= 64) {
} else {
}
}
{
0x011ffffe000UL,
}
{
/* Ignore the slot number of the relocation; GCC and Intel
toolchains differed for some time on whether IMM64 relocs are
against slot 1 (Intel) or slot 2 (GCC). */
0x01fffefe000UL,
);
}
{
/* Ignore the slot number of the relocation; GCC and Intel
toolchains differed for some time on whether IMM64 relocs are
against slot 1 (Intel) or slot 2 (GCC). */
}
{
}
/* Like ia64_imm22(), but also clear bits 20-21. For addl, this has
the effect of turning "addl rX=imm22,rY" into "addl
rX=imm22,r0". */
{
}
{
}
static inline void ia64_nop_b (void *insn)
{
}
{
}
int relaxable)
{
return 0;
}
return 1;
}
struct ia64_fixup {
struct ia64_fixup *next;
void *addr; /* address that needs to be patched */
long value;
};
do { \
} while (0)
do { \
ltoff_fixes = fixup; \
} \
} while (0)
struct ia64_fixup *ltoff_fixes,
struct ia64_fixup *plt_fixes,
int num_plts,
unsigned long *plt_target,
unsigned int *plt_offset)
{
static const uint8_t plt_bundle[] = {
0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; movl r1=GP */
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60,
0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; brl IP */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
};
struct ia64_fixup *fixup;
unsigned int offset = 0;
struct fdesc {
long ip;
long gp;
} *fdesc;
int i;
if (plt_fixes) {
for (i = 0; i < num_plts; ++i) {
if (plt_offset[i]) {
plt_offset[i] = offset;
offset += sizeof(plt_bundle);
gen_code_ptr += sizeof(plt_bundle);
}
}
}
/* First, create the GOT: */
/* first check if we already have this value in the GOT: */
break;
/* Nope, we need to put the value in the GOT: */
gen_code_ptr += 8;
}
}
/* Keep code ptr aligned. */
if ((long) gen_code_ptr & 15)
gen_code_ptr += 8;
}
#endif
#endif
#ifdef CONFIG_DYNGEN_OP
#if defined __hppa__
struct hppa_branch_stub {
long target;
struct hppa_branch_stub *next;
};
do { \
} while (0)
{
uint32_t *p = s + 1;
if (!stub) return;
unsigned long l = (unsigned long)p;
/* stub:
* ldil L'target, %r1
* be,n R'target(%sr4,%r1)
*/
}
/* b,l,n stub,%r0 */
*gen_code_pp = (uint8_t *)p;
}
#endif /* __hppa__ */
{
#ifdef __hppa__
#endif
gen_code_ptr = s->code_ptr;
switch(opc) {
#include "op.h"
default:
tcg_abort();
}
#ifdef __hppa__
#endif
s->code_ptr = gen_code_ptr;
return opparam_ptr;
}
#endif