Esempio n. 1
0
void generate_FUNCSTART(quad* quad){
	struct instruction t0;
	t0.arg1.type = nil_a;
	t0.arg2.type = nil_a;
	t0.result.type= label_a;
	t0.result.val = 0;
	t0.opcode = jump_v;
	add_func_jump(nextinstructionlabel());
	emit_instruction(&t0);



	struct userfunc* f;
	f = (struct userfunc*)malloc(sizeof(struct userfunc));
	f->id=quad->result->sym->name;
	f->address = nextinstructionlabel();
	quad->taddress = nextinstructionlabel();
	userfuncs_newfunc(quad->result->sym);	//added 6/5 ore

	(userFuncs+totalUserFuncs)->address = f->address;
	(userFuncs+totalUserFuncs)->id = f->id;
	(userFuncs+totalUserFuncs)->localSize = quad->result->sym->totallocals;
	f->index = totalUserFuncs-1;
	funcpush(f);

	struct instruction t;
	totalUserFuncs++;
	t.arg1.type = nil_a;
	t.arg2.type = nil_a;
	t.opcode = funcenter_v;
	make_operand(quad->result, &t.result);
	t.result.val = totalUserFuncs-1; //EDW
	emit_instruction(&t);
}
Esempio n. 2
0
void generate_OR (quad* quad) {

	quad->taddress = nextinstructionlabel();
	struct instruction t;

	t.opcode = jeq_v;
	make_operand(quad->arg1, &t.arg1);
	make_booloperand(&t.arg2, '1');
	t.result.type = label_a;
	t.result.val  = nextinstructionlabel()+4;
	emit_instruction(&t);

	make_operand(quad->arg2, &t.arg1);
	t.result.val  = nextinstructionlabel()+3;
	emit_instruction(&t);

	t.opcode = assign_v;
	make_booloperand(&t.arg1, '0');
	reset_operand(&t.arg2);
	make_operand(quad->result, &t.result);
	emit_instruction(&t);

	t.opcode = jump_v;
	reset_operand (&t.arg1);
	reset_operand(&t.arg2);
	t.result.type = label_a;
	t.result.val  = nextinstructionlabel()+2;
	emit_instruction(&t);

	t.opcode = assign_v;
	make_booloperand(&t.arg1, '1');
	reset_operand(&t.arg2);
	make_operand(quad->result, &t.result);
	emit_instruction(&t);
}
Esempio n. 3
0
static bool generate_output()
{
    size_t n;
    uint16_t C, A;

    /* Write header */
    write_data(MAGIC_STR, MAGIC_LEN);

    /* Generate instructions */
    C = A = 0;
    for (n = 0; n < last_num_blocks; ++n)
    {
        if (last_blocks[n].is == NULL)
        {
            /* Check to see if we must start a new instruction */
            if ( (C > 0 && last_blocks[n].offset !=
                           last_blocks[n - 1].offset + BS ) ||
                 (C == 0x7fffu) || (A > 0) )
            {
                emit_instruction(n, C, A);
                C = A = 0;
            }
            ++C;
        }
        else
        {
            if (A == 0x7fffu)
            {
                emit_instruction(n, C, A);
                C = A = 0;
            }
            ++A;
        }
    }

    /* Emit final instruction (if necessary) */
    if (C > 0 || A > 0) emit_instruction(last_num_blocks, C, A);

    /* Write end-of-instructions */
    write_uint32(0xffffffffu);
    write_uint16(0xffffu);
    write_uint16(0xffffu);

    /* Add last file digest */
    write_data(last_digest, DS);

    /* Add first file digest (if known) */
    if (!orig_digest_known)
    {
        fprintf(stderr, "WARNING: original file digest unknown; "
                        "generating version 1.0 differences file.\n");
    }
    else
    {
        write_data(orig_digest, DS);
    }

    return true;
}
Esempio n. 4
0
/**
 * Declare a VS input register.
 * We still make up the input semantics the same as in 2.0
 */
static boolean
vs30_input(struct svga_shader_emitter *emit,
           struct tgsi_declaration_semantic semantic,
           unsigned idx)
{
   SVGA3DOpDclArgs dcl;
   SVGA3dShaderInstToken opcode;
   unsigned usage, index;

   opcode = inst_token( SVGA3DOP_DCL );
   dcl.values[0] = 0;
   dcl.values[1] = 0;

   emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
   dcl.dst = dst_register( SVGA3DREG_INPUT, idx );

   assert(dcl.dst.reserved0);

   svga_generate_vdecl_semantics( idx, &usage, &index );

   dcl.usage = usage;
   dcl.index = index;
   dcl.values[0] |= 1<<31;

   return (emit_instruction(emit, opcode) &&
           svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
}
Esempio n. 5
0
static boolean vs20_input( struct svga_shader_emitter *emit,
                           struct tgsi_declaration_semantic semantic,
                           unsigned idx )
{
   SVGA3DOpDclArgs dcl;
   SVGA3dShaderInstToken opcode;

   opcode = inst_token( SVGA3DOP_DCL );
   dcl.values[0] = 0;
   dcl.values[1] = 0;

   emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
   dcl.dst = dst_register( SVGA3DREG_INPUT, idx );

   assert(dcl.dst.reserved0);

   /* Mesa doesn't provide use with VS input semantics (they're
    * actually pretty meaningless), so we just generate some plausible
    * ones here.  This has to match what we declare in the vdecl code
    * in svga_pipe_vertex.c.
    */
   if (idx == 0) {
      dcl.usage = SVGA3D_DECLUSAGE_POSITION;
      dcl.index = 0;
   }
   else {
      dcl.usage = SVGA3D_DECLUSAGE_TEXCOORD;
      dcl.index = idx - 1;
   }

   dcl.values[0] |= 1<<31;

   return  (emit_instruction(emit, opcode) &&
            svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
}
Esempio n. 6
0
/**
 * Emit a PS input (or VS depth/fog output) register declaration.
 * For example, if usage = SVGA3D_DECLUSAGE_TEXCOORD, reg.num = 1, and
 * index = 3, we'll emit "dcl_texcoord3 v1".
 */
static boolean
emit_decl(struct svga_shader_emitter *emit,
          SVGA3dShaderDestToken reg,
          unsigned usage, 
          unsigned index)
{
   SVGA3DOpDclArgs dcl;
   SVGA3dShaderInstToken opcode;

   /* check values against bitfield sizes */
   assert(index < 16);
   assert(usage <= SVGA3D_DECLUSAGE_MAX);

   opcode = inst_token( SVGA3DOP_DCL );
   dcl.values[0] = 0;
   dcl.values[1] = 0;

   dcl.dst = reg;
   dcl.usage = usage;
   dcl.index = index;
   dcl.values[0] |= 1<<31;

   return (emit_instruction(emit, opcode) &&
           svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
}
Esempio n. 7
0
/*
 * Main function - glue everything together.
 */
int
main ( int argc, char **argv )
{
    // Initialize the state machine (if neccessary)
    init_transtab ();

    // Print a bit of startup, to start drawing somewhere sensible
    printf ( "newpath\n%d %d moveto\n", x, y );

    // Make sure the loop below runs at least once (the value given
    // here will be discarded in the first iteration) 
    command_t c = MOVE;
	
	//Test commands
	/*draw();
	turn();
	draw();
	move();
	draw();*/

    // Until the end of the input stream,
    while ( c != END )
    {
        c = next(stdin);     // Read until we have a token
        emit_instruction(c); // Emit the instruction it stands for
    }

    // Finalize by drawing the traced path, and exiting
    printf ( "stroke\nshowpage\n" );
    exit ( EXIT_SUCCESS );
}
Esempio n. 8
0
void generate_GETRETVAL(quad* quad) {
	quad->taddress = nextinstructionlabel();
	struct instruction t;
	t.opcode = assign_v;
	make_operand(quad->result, &t.result);
	make_retvaloperand(&t.arg1);
	emit_instruction(&t);
}
Esempio n. 9
0
void generate_CALL(quad* quad) {
	quad->taddress = nextinstructionlabel();
	struct instruction t;
	t.opcode = call_v;
	t.arg1.type = nil_a;
	t.arg2.type = nil_a;
	make_operand(quad->result, &t.result);
	emit_instruction(&t);
}
Esempio n. 10
0
static INLINE void
emit_i(struct ppc_function *p, uint op, uint li, uint aa, uint lk)
{
   union i_inst inst;
   inst.inst.op = op;
   inst.inst.li = li;
   inst.inst.aa = aa;
   inst.inst.lk = lk;
   emit_instruction(p, inst.bits);
}
Esempio n. 11
0
void generate_instr(enum vmopcode op,quad* quad){
	struct instruction t;
	t.opcode = op;
	if(op==23){
		printf("element:%lf,type:%d\n",quad->arg1->numConst,quad->arg1->type );
	}
	make_operand(quad->arg1, &(t.arg1));
	make_operand(quad->arg2, &(t.arg2));
	make_operand(quad->result, &(t.result));
	quad->taddress = nextinstructionlabel();
	emit_instruction(&t);
}
Esempio n. 12
0
void generate_RETURN(quad* quad){
	quad->taddress = nextinstructionlabel();
	struct instruction t;
	t.opcode = assign_v;
	make_retvaloperand(&t.result);
	t.arg2.type=nil_a;
	make_operand(quad->arg1, &t.arg1);
	emit_instruction(&t);

	struct userfunc* f;
	f = functop(funcstack);
	f->returnList = (struct userfunc*)malloc(sizeof(struct userfunc));
	append(f->returnList, nextinstructionlabel());

	t.opcode = jump_v;
	reset_operand(&t.arg1);
	t.arg1.type = nil_a;
	reset_operand(&t.arg2);
	t.result.type = label_a;
	//printf("%d  LABEL_A\n",f->returnList->address);
	emit_instruction(&t);
}
Esempio n. 13
0
static INLINE void
emit_xl(struct ppc_function *p, uint op, uint bo, uint bi, uint bh,
        uint op2, uint lk)
{
   union xl_inst inst;
   inst.inst.op = op;
   inst.inst.bo = bo;
   inst.inst.bi = bi;
   inst.inst.unused = 0x0;
   inst.inst.bh = bh;
   inst.inst.op2 = op2;
   inst.inst.lk = lk;
   emit_instruction(p, inst.bits);
}
Esempio n. 14
0
void generate_FUNCEND(quad* quad){
	struct userfunc* f;
	f=funcpop(funcstack);
	patch_returns(f->returnList, nextinstructionlabel());
	quad->taddress = nextinstructionlabel();
	struct instruction t;
	t.opcode = funcexit_v;
	t.arg1.type = nil_a;
	t.arg2.type = nil_a;
	make_operand(quad->result, &t.result);
	t.result.val = f->index;
	patch_func_jump(quad->taddress);
	emit_instruction(&t);
}
Esempio n. 15
0
void generate_relational (int op,quad* quad) {
	struct instruction t;
	t.opcode = op;
	// printf("arg1:%d,arg2:%d\n", quad->arg1->boolConst,quad->arg2->boolConst);
	make_operand(quad->arg1, &t.arg1);
	make_operand(quad->arg2, &t.arg2);
	t.result.type = label_a;
	if (quad->label < currprocessedquad())
		t.result.val = (quads+quad->label)->taddress;
	else
		add_incomplete_jump(nextinstructionlabel(), quad->label);
	quad->taddress = nextinstructionlabel();
	emit_instruction(&t);
}
Esempio n. 16
0
static boolean ps20_input( struct svga_shader_emitter *emit,
                           struct tgsi_declaration_semantic semantic,
                           unsigned idx )
{
   struct src_register reg;
   SVGA3DOpDclArgs dcl;
   SVGA3dShaderInstToken opcode;

   opcode = inst_token( SVGA3DOP_DCL );
   dcl.values[0] = 0;
   dcl.values[1] = 0;

   switch (semantic.SemanticName) {
   case TGSI_SEMANTIC_POSITION:
      /* Special case:
       */
      reg = src_register( SVGA3DREG_MISCTYPE, 
                          SVGA3DMISCREG_POSITION );
      break;
   case TGSI_SEMANTIC_COLOR:
      reg = src_register( SVGA3DREG_INPUT, 
                          semantic.SemanticIndex );
      break;
   case TGSI_SEMANTIC_FOG:
      assert(semantic.SemanticIndex == 0);
      reg = src_register( SVGA3DREG_TEXTURE, 0 );
      break;
   case TGSI_SEMANTIC_GENERIC:
      reg = src_register( SVGA3DREG_TEXTURE,
                          semantic.SemanticIndex + 1 );
      break;
   default:
      assert(0);
      return TRUE;
   }

   emit->input_map[idx] = reg;

   dcl.dst = dst( reg );

   dcl.usage = 0;
   dcl.index = 0;

   dcl.values[0] |= 1<<31;

   return  (emit_instruction(emit, opcode) &&
            svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
}
Esempio n. 17
0
static INLINE void
emit_va(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB, uint vC,
        const char *format)
{
   union va_inst inst;
   inst.inst.op = 4;
   inst.inst.vD = vD;
   inst.inst.vA = vA;
   inst.inst.vB = vB;
   inst.inst.vC = vC;
   inst.inst.op2 = op2;
   emit_instruction(p, inst.bits);
   if (p->print) {
      indent(p);
      printf(format, vD, vA, vB, vC);
   }
}
Esempio n. 18
0
static INLINE void
emit_x(struct ppc_function *p, uint op, uint vrs, uint ra, uint rb, uint op2,
       const char *format)
{
   union x_inst inst;
   inst.inst.op = op;
   inst.inst.vrs = vrs;
   inst.inst.ra = ra;
   inst.inst.rb = rb;
   inst.inst.op2 = op2;
   inst.inst.unused = 0x0;
   emit_instruction(p, inst.bits);
   if (p->print) {
      indent(p);
      printf(format, vrs, ra, rb);
   }
}
Esempio n. 19
0
static boolean ps20_sampler( struct svga_shader_emitter *emit,
                          struct tgsi_declaration_semantic semantic,
                          unsigned idx )
{
   SVGA3DOpDclArgs dcl;
   SVGA3dShaderInstToken opcode;

   opcode = inst_token( SVGA3DOP_DCL );
   dcl.values[0] = 0;
   dcl.values[1] = 0;

   dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx );
   dcl.type = svga_tgsi_sampler_type( emit, idx );

   return  (emit_instruction(emit, opcode) &&
            svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
}
Esempio n. 20
0
static INLINE void
emit_a(struct ppc_function *p, uint op, uint frt, uint fra, uint frb, uint op2,
       uint rc, const char *format)
{
   union a_inst inst;
   inst.inst.op = op;
   inst.inst.frt = frt;
   inst.inst.fra = fra;
   inst.inst.frb = frb;
   inst.inst.unused = 0x0;
   inst.inst.op2 = op2;
   inst.inst.rc = rc;
   emit_instruction(p, inst.bits);
   if (p->print) {
      indent(p);
      printf(format, frt, fra, frb);
   }
}
Esempio n. 21
0
static INLINE void
emit_xo(struct ppc_function *p, uint op, uint rt, uint ra, uint rb, uint oe,
        uint op2, uint rc, const char *format)
{
   union xo_inst inst;
   inst.inst.op = op;
   inst.inst.rt = rt;
   inst.inst.ra = ra;
   inst.inst.rb = rb;
   inst.inst.oe = oe;
   inst.inst.op2 = op2;
   inst.inst.rc = rc;
   emit_instruction(p, inst.bits);
   if (p->print) {
      indent(p);
      printf(format, rt, ra, rb);
   }
}
Esempio n. 22
0
/**
 * Declare a VS input register.
 * We still make up the input semantics the same as in 2.0
 */
static boolean
vs30_input(struct svga_shader_emitter *emit,
           struct tgsi_declaration_semantic semantic,
           unsigned idx)
{
   SVGA3DOpDclArgs dcl;
   SVGA3dShaderInstToken opcode;
   unsigned usage, index;

   opcode = inst_token( SVGA3DOP_DCL );
   dcl.values[0] = 0;
   dcl.values[1] = 0;

   if (emit->key.vkey.zero_stride_vertex_elements & (1 << idx)) {
      unsigned i;
      unsigned offset = 0;
      unsigned start_idx = emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
      /* adjust for prescale constants */
      start_idx += emit->key.vkey.need_prescale ? 2 : 0;
      /* compute the offset from the start of zero stride constants */
      for (i = 0; i < PIPE_MAX_ATTRIBS && i < idx; ++i) {
         if (emit->key.vkey.zero_stride_vertex_elements & (1<<i))
            ++offset;
      }
      emit->input_map[idx] = src_register( SVGA3DREG_CONST,
                                           start_idx + offset );
   } else {
      emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
      dcl.dst = dst_register( SVGA3DREG_INPUT, idx );

      assert(dcl.dst.reserved0);

      svga_generate_vdecl_semantics( idx, &usage, &index );

      dcl.usage = usage;
      dcl.index = index;
      dcl.values[0] |= 1<<31;

      return (emit_instruction(emit, opcode) &&
              svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
   }
   return TRUE;
}
Esempio n. 23
0
static INLINE void
emit_vx(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB,
        const char *format, boolean transpose)
{
   union vx_inst inst;
   inst.inst.op = 4;
   inst.inst.vD = vD;
   inst.inst.vA = vA;
   inst.inst.vB = vB;
   inst.inst.op2 = op2;
   emit_instruction(p, inst.bits);
   if (p->print) {
      indent(p);
      if (transpose)
         printf(format, vD, vB, vA);
      else
         printf(format, vD, vA, vB);
   }
}
Esempio n. 24
0
static INLINE void
emit_d(struct ppc_function *p, uint op, uint rt, uint ra, int si,
       const char *format, boolean transpose)
{
   union d_inst inst;
   assert(si >= -32768);
   assert(si <= 32767);
   inst.inst.op = op;
   inst.inst.rt = rt;
   inst.inst.ra = ra;
   inst.inst.si = (unsigned) (si & 0xffff);
   emit_instruction(p, inst.bits);
   if (p->print) {
      indent(p);
      if (transpose)
         printf(format, rt, si, ra);
      else
         printf(format, rt, ra, si);
   }
}
Esempio n. 25
0
void NativeGenerator::generate_native_string_entries() {

  comment_section("Native entry points for string functions");
  {

    //--------------------java.lang.String.indexof0---------------------------
    rom_linkable_entry("native_string_indexof0_entry");

    wtk_profile_quick_call(/* param_size*/ 2);

    comment("Pop the return address");
    popl(edi);
    comment("Push zero for fromIndex");
    pushl(Constant(0));
    comment("Push back the return address");
    pushl(edi);

    jmp(Constant("native_string_indexof_entry"));
    rom_linkable_entry_end(); // native_string_indexof0_entry

    //--------------------java.lang.String.indexof---------------------------

    rom_linkable_entry("native_string_indexof_entry");
    Label cont, loop, test, failure, success;

    wtk_profile_quick_call(/* param_size*/ 3);

    comment("Pop the return address");
    popl(edi);

    comment("Pop the argument: fromIndex");
    pop_int(eax, eax);

    comment("Pop the argument: ch");
    pop_int(ebx, ebx);

    comment("Pop the receiver");
    pop_obj(ecx, ecx);

    cmpl(ebx, Constant(0xFFFF));
    jcc(greater, Constant(failure));

    cmpl(eax, Constant(0));
    jcc(greater_equal, Constant(cont));
    movl(eax, Constant(0));

    bind(cont);
    movl(esi, Address(ecx, Constant(String::count_offset())));

    comment("if (fromIndex >= count) { return -1; }");
    cmpl(eax, esi);
    jcc(greater_equal, Constant(failure));

    movl(edx, Address(ecx, Constant(String::offset_offset())));
    addl(eax, edx); // i = offset + fromIndex
    addl(edx, esi); // int max = offset + count;
    movl(esi, Address(ecx, Constant(String::value_offset())));    // v = value.
    jmp(Constant(test));

    bind(loop);
    cmpw(Address(esi, eax, times_2, Constant(Array::base_offset())),  ebx);
    jcc(equal, Constant(success));
    incl(eax);

    bind(test);
    cmpl(eax, edx);
    jcc(less, Constant(loop));

    comment("Return -1 by pushing the value and jumping to the return address");
    bind(failure);
    push_int(-1);
    jmp(edi);

    comment("Return i - offset by pushing the value and jumping to the return address");
    bind(success);
    movl(esi, Address(ecx, Constant(String::offset_offset())));   // i = offset + fromIndex
    subl(eax, esi);
    push_int(eax);
    jmp(edi);

    rom_linkable_entry_end(); // native_string_indexof_entry
  }

  //----------------------java.lang.String.charAt---------------------------

  {
    rom_linkable_entry("native_string_charAt_entry");
    if (AddExternCUnderscore) {
      emit_instruction("jmp _interpreter_method_entry");
    } else {
      emit_instruction("jmp  interpreter_method_entry");
    }
    rom_linkable_entry_end();
  }

  //----------------------java.lang.String(java.lang.StringBuffer)-------------

  {
    rom_linkable_entry("native_string_init_entry");
    if (AddExternCUnderscore) {
      emit_instruction("jmp _interpreter_method_entry");
    } else {
      emit_instruction("jmp  interpreter_method_entry");
    }
    rom_linkable_entry_end();
  }

  //----------------------java.lang.String.equals(java.lang.Object)------------

  {
    rom_linkable_entry("native_string_equals_entry");
    if (AddExternCUnderscore) {
      emit_instruction("jmp _interpreter_method_entry");
    } else {
      emit_instruction("jmp  interpreter_method_entry");
    }
    rom_linkable_entry_end();
  }

  //----------------------java.lang.String.indexOf(java.lang.String)-----------

  {
    rom_linkable_entry("native_string_indexof0_string_entry");
    if (AddExternCUnderscore) {
      emit_instruction("jmp _interpreter_method_entry");
    } else {
      emit_instruction("jmp  interpreter_method_entry");
    }
    rom_linkable_entry_end();
  }

  //----------------------java.lang.String.indexOf(java.lang.String)-----------

  {
    rom_linkable_entry("native_string_indexof_string_entry");
    if (AddExternCUnderscore) {
      emit_instruction("jmp _interpreter_method_entry");
    } else {
      emit_instruction("jmp  interpreter_method_entry");
    }
    rom_linkable_entry_end();
  }

  //----------------------java.lang.String.compareTo---------------------------

  { // java.lang.String.compareTo
    // Method int compareTo(java.lang.String)

    rom_linkable_entry("native_string_compareTo_entry");

    wtk_profile_quick_call(/* param_size*/ 2);

    comment("preserve method");
    pushl(ebx);

    // 8 is return address plus pushed method
    int  str1_offset =  JavaFrame::arg_offset_from_sp(0) + 8,
         str0_offset =  JavaFrame::arg_offset_from_sp(1) + 8;

    comment("load arguments to registers");
    movl(ecx, Address(esp, Constant(str1_offset)));
    movl(eax, Address(esp, Constant(str0_offset)));

    // eax: str0: this String
    // ebx: str1: String to compare against

    Label bailout;

    comment("Null check");
    testl(ecx, ecx);
    jcc(zero, Constant(bailout));

    comment("get str0.value[]");
    movl(esi, Address(eax, Constant(String::value_offset())));
    comment("get str0.offset");
    movl(ebx, Address(eax, Constant(String::offset_offset())));
    comment("compute start of character data");
    leal(esi, Address(esi, ebx, times_2, Constant(Array::base_offset())));
    comment("get str0.count");
    movl(eax, Address(eax, Constant(String::count_offset())));

    comment("get str1.value[]");
    movl(edi, Address(ecx, Constant(String::value_offset())));
    comment("get str1.offset");
    movl(ebx, Address(ecx, Constant(String::offset_offset())));
    comment("compute start of character data");
    leal(edi, Address(edi, ebx, times_2, Constant(Array::base_offset())));
    comment("get str1.count");
    movl(ebx, Address(ecx, Constant(String::count_offset())));

    // esi = str0 start of character data
    // edi = str1 start of character data
    // eax = str0 length
    // ebx = str1 length

    Label str1_longest;
    subl(eax, ebx);
    jcc(greater_equal, Constant(str1_longest));
    // str1 is longer than str0
    addl(ebx, eax);
    bind(str1_longest);

    // esi = str0 start of character data
    // edi = str1 start of character data
    // eax = str0.count - str1.count
    // ebx = min(str0.count, str1.count)

    // save str0.count - str1.count, we might need it later
    pushl(eax);

    xorl(ecx, ecx);

    Label loop, check_lengths, done;
    bind(loop);
    cmpl(ecx, ebx);
    jcc(above_equal, Constant(check_lengths));
    movzxw(eax, Address(esi, ecx, times_2));
    movzxw(edx, Address(edi, ecx, times_2));
    subl(eax, edx);
    jcc(not_equal, Constant(done));
    incl(ecx);
    jmp(Constant(loop));

    bind(check_lengths);
    movl(eax, Address(esp));

    bind(done);
    popl(ebx); // remove saved length difference

    // Push result on stack and return to caller
    popl(ebx);     // remove method
    popl(edi);     // pop return address
    addl(esp, Constant(2 * BytesPerStackElement)); // remove arguments
    push_int(eax); // push result
    jmp(edi);      // return

    comment("Bail out to the general compareTo implementation");
    bind(bailout);
    comment("pop method");
    popl(ebx);
    if (AddExternCUnderscore) {
      emit_instruction("jmp _interpreter_method_entry");
    } else {
      emit_instruction("jmp  interpreter_method_entry");
    }

    rom_linkable_entry_end(); // native_string_compareTo_entry
  }

  //----------------------java.lang.String.endsWith----------------

  {
    // java.lang.String.endsWith
    // Method boolean endsWith(java.lang.String)

    rom_linkable_entry("native_string_endsWith_entry");

    wtk_profile_quick_call(/* param_size*/ 2);

    Label bailout;

    // 4 is return address
    int suffix_offset =  JavaFrame::arg_offset_from_sp(0) + 4,
        this_offset =  JavaFrame::arg_offset_from_sp(1) + 4;

    comment("load arguments to registers");
    movl(eax, Address(esp, Constant(suffix_offset)));
    cmpl(eax, Constant(0));
    jcc(equal, Constant(bailout));

    movl(ecx, Address(esp, Constant(this_offset)));

    comment("Pop the return address");
    popl(edi);

    movl(edx, Address(ecx, Constant(String::count_offset())));
    subl(edx, Address(eax, Constant(String::count_offset())));

    comment("Push (this.count - suffix.count) for toffset");
    pushl(edx);

    comment("Push back the return address");
    pushl(edi);

    jmp(Constant("native_string_startsWith_entry"));

    comment("Bail out to the general startsWith implementation");
    bind(bailout);
    if (AddExternCUnderscore) {
      emit_instruction("jmp _interpreter_method_entry");
    } else {
      emit_instruction("jmp  interpreter_method_entry");
    }

    rom_linkable_entry_end(); // native_string_endsWith_entry
  }

  //----------------------java.lang.String.startsWith----------------
  {
    // java.lang.String.startsWith
    // Method boolean startsWith(java.lang.String)
    rom_linkable_entry("native_string_startsWith0_entry");

    wtk_profile_quick_call(/* param_size*/ 2);
    Label bailout;

    // 4 is return address
    int prefix_offset = JavaFrame::arg_offset_from_sp(0) + 4;

    comment("Check if prefix is null");
    cmpl(Address(esp, Constant(prefix_offset)), Constant(0));
    jcc(equal, Constant(bailout));

    comment("Pop the return address");
    popl(edi);
    comment("Push zero for toffset");
    pushl(Constant(0));
    comment("Push back the return address");
    pushl(edi);

    jmp(Constant("native_string_startsWith_entry"));

    comment("Bail out to the general startsWith implementation");
    bind(bailout);
    if (AddExternCUnderscore) {
      emit_instruction("jmp _interpreter_method_entry");
    } else {
      emit_instruction("jmp  interpreter_method_entry");
    }

    rom_linkable_entry_end(); // native_string_startsWith0_entry
  }

  {
    // ----------- java.lang.String.startsWith ------------------------------
    // Method boolean startsWith(java.lang.String,int)

    rom_linkable_entry("native_string_startsWith_entry");

    wtk_profile_quick_call(/* param_size*/ 3);

    Label bailout, return_false;

    // 4 is return address
    int  prefix_offset =  JavaFrame::arg_offset_from_sp(1) + 4;

    comment("Check if prefix is null");
    cmpl(Address(esp, Constant(prefix_offset)), Constant(0));
    jcc(equal, Constant(bailout));

    comment("Pop the return address");
    popl(edi);

    comment("Pop the argument: toffset");
    pop_int(edx, edx);

    comment("Pop the argument: prefix");
    pop_obj(eax, eax);

    comment("Pop the receiver");
    pop_obj(ecx, ecx);

    comment("Preserve the return address");
    pushl(edi);

    // ecx: this String
    // eax: prefix

    cmpl(edx, Constant(0));
    jcc(less, Constant(return_false));

    comment("if (toffset > this.count - prefix.count) return false;");
    movl(ebx, Address(ecx, Constant(String::count_offset())));
    subl(ebx, Address(eax, Constant(String::count_offset())));
    cmpl(edx, ebx);
    jcc(greater, Constant(return_false));

    comment("get this.value[]");
    movl(esi, Address(ecx, Constant(String::value_offset())));
    comment("get this.offset");
    movl(ebx, Address(ecx, Constant(String::offset_offset())));
    comment("add toffset");
    addl(ebx, edx);
    comment("compute start of character data");
    leal(esi, Address(esi, ebx, times_2, Constant(Array::base_offset())));

    comment("get prefix.value[]");
    movl(edi, Address(eax, Constant(String::value_offset())));
    comment("get prefix.offset");
    movl(ebx, Address(eax, Constant(String::offset_offset())));
    comment("compute start of character data");
    leal(edi, Address(edi, ebx, times_2, Constant(Array::base_offset())));

    comment("get prefix.count");
    movl(ecx, Address(eax, Constant(String::count_offset())));
    comment("get the number of bytes to compare");
    shll(ecx, Constant(1));

    comment("memcmp(edi, esi, ecx);");
    pushl(ecx);
    pushl(esi);
    pushl(edi);

    if (GenerateInlineAsm) {
      // VC++ treats memcmp() as an intrinsic function and would cause
      // reference to memcmp in Interpreter_i386.c to fail to compile.
      call(Constant("memcmp_from_interpreter"));
    } else {
      call(Constant("memcmp"));
    }
    addl(esp, Constant(12));
    cmpl(eax, Constant(0));
    jcc(not_equal, Constant(return_false));

    // Push 1 on stack and return to caller
    popl(edi);     // pop return address
    push_int(1);   // push result
    jmp(edi);      // return

    bind(return_false);
    // Push 0 on stack and return to caller
    popl(edi);     // pop return address
    push_int(0);   // push result
    jmp(edi);      // return

    comment("Bail out to the general startsWith implementation");
    bind(bailout);
    if (AddExternCUnderscore) {
      emit_instruction("jmp _interpreter_method_entry");
    } else {
      emit_instruction("jmp  interpreter_method_entry");
    }

    rom_linkable_entry_end(); // native_string_startsWith_entry
  }
}
Esempio n. 26
0
void generate_NOP ()								{ struct instruction t; t.opcode=nop_v; emit_instruction(&t); }
void
lp_build_tgsi_aos(LLVMBuilderRef builder,
                  const struct tgsi_token *tokens,
                  struct lp_type type,
                  const unsigned char swizzles[4],
                  LLVMValueRef consts_ptr,
                  const LLVMValueRef *inputs,
                  LLVMValueRef *outputs,
                  struct lp_build_sampler_aos *sampler,
                  const struct tgsi_shader_info *info)
{
   struct lp_build_tgsi_aos_context bld;
   struct tgsi_parse_context parse;
   uint num_immediates = 0;
   uint num_instructions = 0;
   unsigned chan;
   int pc = 0;

   /* Setup build context */
   memset(&bld, 0, sizeof bld);
   lp_build_context_init(&bld.base, builder, type);
   lp_build_context_init(&bld.int_bld, builder, lp_int_type(type));

   for (chan = 0; chan < 4; ++chan) {
      bld.swizzles[chan] = swizzles[chan];
      bld.inv_swizzles[swizzles[chan]] = chan;
   }

   bld.inputs = inputs;
   bld.outputs = outputs;
   bld.consts_ptr = consts_ptr;
   bld.sampler = sampler;
   bld.indirect_files = info->indirect_files;
   bld.instructions = (struct tgsi_full_instruction *)
                      MALLOC(LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction));
   bld.max_instructions = LP_MAX_INSTRUCTIONS;

   if (!bld.instructions) {
      return;
   }

   tgsi_parse_init(&parse, tokens);

   while (!tgsi_parse_end_of_tokens(&parse)) {
      tgsi_parse_token(&parse);

      switch(parse.FullToken.Token.Type) {
      case TGSI_TOKEN_TYPE_DECLARATION:
         /* Inputs already interpolated */
         emit_declaration(&bld, &parse.FullToken.FullDeclaration);
         break;

      case TGSI_TOKEN_TYPE_INSTRUCTION:
         {
            /* save expanded instruction */
            if (num_instructions == bld.max_instructions) {
               struct tgsi_full_instruction *instructions;
               instructions = REALLOC(bld.instructions,
                                      bld.max_instructions
                                      * sizeof(struct tgsi_full_instruction),
                                      (bld.max_instructions + LP_MAX_INSTRUCTIONS)
                                      * sizeof(struct tgsi_full_instruction));
               if (!instructions) {
                  break;
               }
               bld.instructions = instructions;
               bld.max_instructions += LP_MAX_INSTRUCTIONS;
            }

            memcpy(bld.instructions + num_instructions,
                   &parse.FullToken.FullInstruction,
                   sizeof(bld.instructions[0]));

            num_instructions++;
         }

         break;

      case TGSI_TOKEN_TYPE_IMMEDIATE:
         /* simply copy the immediate values into the next immediates[] slot */
         {
            const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
            float imm[4];
            assert(size <= 4);
            assert(num_immediates < LP_MAX_TGSI_IMMEDIATES);
            for (chan = 0; chan < 4; ++chan) {
               imm[chan] = 0.0f;
            }
            for (chan = 0; chan < size; ++chan) {
               unsigned swizzle = bld.swizzles[chan];
               imm[swizzle] = parse.FullToken.FullImmediate.u[chan].Float;
            }
            bld.immediates[num_immediates] =
                     lp_build_const_aos(type,
                                        imm[0], imm[1], imm[2], imm[3],
                                        NULL);
            num_immediates++;
         }
         break;

      case TGSI_TOKEN_TYPE_PROPERTY:
         break;

      default:
         assert(0);
      }
   }

   while (pc != -1) {
      struct tgsi_full_instruction *instr = bld.instructions + pc;
      const struct tgsi_opcode_info *opcode_info =
         tgsi_get_opcode_info(instr->Instruction.Opcode);
      if (!emit_instruction(&bld, instr, opcode_info, &pc))
         _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
                       opcode_info->mnemonic);
   }

   if (0) {
      LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
      LLVMValueRef function = LLVMGetBasicBlockParent(block);
      debug_printf("11111111111111111111111111111 \n");
      tgsi_dump(tokens, 0);
      lp_debug_dump_value(function);
      debug_printf("2222222222222222222222222222 \n");
   }
   tgsi_parse_free(&parse);

   if (0) {
      LLVMModuleRef module = LLVMGetGlobalParent(
         LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld.base.builder)));
      LLVMDumpModule(module);
   }

   FREE(bld.instructions);
}
Esempio n. 28
0
/**
 * Declare a VS output.
 * VS3.0 outputs have proper declarations and semantic info for
 * matching against PS inputs.
 */
static boolean
vs30_output(struct svga_shader_emitter *emit,
            struct tgsi_declaration_semantic semantic,
            unsigned idx)
{
   SVGA3DOpDclArgs dcl;
   SVGA3dShaderInstToken opcode;
   unsigned usage, index;

   opcode = inst_token( SVGA3DOP_DCL );
   dcl.values[0] = 0;
   dcl.values[1] = 0;

   if (!translate_vs_ps_semantic( emit, semantic, &usage, &index ))
      return FALSE;

   if (emit->vs30_output_count >= SVGA3D_OUTPUTREG_MAX)
      return FALSE;

   dcl.dst = dst_register( SVGA3DREG_OUTPUT, emit->vs30_output_count++ );
   dcl.usage = usage;
   dcl.index = index;
   dcl.values[0] |= 1<<31;

   if (semantic.Name == TGSI_SEMANTIC_POSITION) {
      assert(idx == 0);
      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
                                            emit->nr_hw_temp++ );
      emit->temp_pos = emit->output_map[idx];
      emit->true_pos = dcl.dst;

      /* Grab an extra output for the depth output */
      if (!vs30_output_emit_depth_fog( emit, &emit->depth_pos ))
         return FALSE;

   }
   else if (semantic.Name == TGSI_SEMANTIC_PSIZE) {
      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
                                            emit->nr_hw_temp++ );
      emit->temp_psiz = emit->output_map[idx];

      /* This has the effect of not declaring psiz (below) and not 
       * emitting the final MOV to true_psiz in the postamble.
       */
      if (!emit->key.vs.allow_psiz)
         return TRUE;

      emit->true_psiz = dcl.dst;
   }
   else if (semantic.Name == TGSI_SEMANTIC_FOG) {
      /*
       * Fog is shared with depth.
       * So we need to decrement out_count since emit_depth_fog will increment it.
       */
      emit->vs30_output_count--;

      if (!vs30_output_emit_depth_fog( emit, &emit->output_map[idx] ))
         return FALSE;

      return TRUE;
   }
   else {
      emit->output_map[idx] = dcl.dst;
   }

   return (emit_instruction(emit, opcode) &&
           svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
}
Esempio n. 29
0
void NativeGenerator::generate_native_system_entries() {
  comment_section("Native entry points for system functions");

  rom_linkable_entry("native_jvm_unchecked_byte_arraycopy_entry");
  jmp(Constant("native_system_arraycopy_entry"));
  rom_linkable_entry_end();

  rom_linkable_entry("native_jvm_unchecked_char_arraycopy_entry");
  jmp(Constant("native_system_arraycopy_entry"));
  rom_linkable_entry_end();

  rom_linkable_entry("native_jvm_unchecked_int_arraycopy_entry");
  jmp(Constant("native_system_arraycopy_entry"));
  rom_linkable_entry_end();

  rom_linkable_entry("native_jvm_unchecked_long_arraycopy_entry");
  jmp(Constant("native_system_arraycopy_entry"));
  rom_linkable_entry_end();

  rom_linkable_entry("native_jvm_unchecked_obj_arraycopy_entry");
  jmp(Constant("native_system_arraycopy_entry"));
  rom_linkable_entry_end();

  rom_linkable_entry("native_system_arraycopy_entry");

  wtk_profile_quick_call(/* param_size*/ 5);

  Label bailout, cont, try_2_byte, try_4_byte, try_8_byte, do_4_byte;

  //  public static native void arraycopy(Object src, int src_position,
  //                                      Object dst, int dst_position,
  //                                      int length);
  comment("preserve method");
  pushl(ebx);

  // 8 is for the preserved method and the return address
  int  length_offset  =  JavaFrame::arg_offset_from_sp(0) + 8,
       dst_pos_offset =  JavaFrame::arg_offset_from_sp(1) + 8,
       dst_offset     =  JavaFrame::arg_offset_from_sp(2) + 8,
       src_pos_offset =  JavaFrame::arg_offset_from_sp(3) + 8,
       src_offset     =  JavaFrame::arg_offset_from_sp(4) + 8;

  comment("load arguments to registers");
  movl(ecx, Address(esp, Constant(length_offset)));
  movl(edi, Address(esp, Constant(dst_pos_offset)));
  movl(edx, Address(esp, Constant(dst_offset)));
  movl(esi, Address(esp, Constant(src_pos_offset)));
  movl(eax, Address(esp, Constant(src_offset)));

  // eax = src
  // ebx = tmp register
  // edx = dst
  // ecx = length
  // esi = src_pos
  // edi = dst_pos

  comment("if (src == NULL) goto bailout;");
  testl( eax, eax );
  jcc(zero, Constant(bailout));

  comment("if (dst == NULL) goto bailout;");
  testl( edx, edx );
  jcc(zero, Constant(bailout));

  comment("if (length < 0 || src_pos < 0 || dst_pos < 0) goto bailout;");
  movl(ebx, ecx);
  orl(ebx, esi);
  orl(ebx, edi);
  jcc(negative, Constant(bailout));

  comment("if ((unsigned int) dst.length < (unsigned int) dst_pos + (unsigned int) length) goto bailout;");
  movl(ebx, ecx);
  addl(ebx, edi);
  cmpl(Address(edx, Constant(Array::length_offset())), ebx);
  jcc(below, Constant(bailout));

  comment("if ((unsigned int) src.length < (unsigned int) src_pos + (unsigned int) length) goto bailout;");
  movl(ebx, ecx);
  addl(ebx, esi);
  cmpl(Address(eax, Constant(Array::length_offset())), ebx);
  jcc(below, Constant(bailout));

  comment("Same near test");
  comment("if (src.near != dst.near) goto bailout;");
  movl(ebx, Address(eax, Constant(Oop::klass_offset())));
  cmpl(ebx, Address(edx, Constant(Oop::klass_offset())));
  jcc(not_equal, Constant(bailout));

  comment("load the instance_size");
  movl(ebx, Address(ebx, Constant(JavaNear::klass_offset())));
  movsxw(ebx, Address(ebx, Constant(FarClass::instance_size_offset())));

  comment("if (instance_size != size_type_array_1()) goto try_2_byte");
  cmpl(ebx, Constant(InstanceSize::size_type_array_1));
  jcc(not_equal, Constant(try_2_byte));
  leal(esi, Address(eax, esi, times_1, Constant(Array::base_offset())));
  leal(edi, Address(edx, edi, times_1, Constant(Array::base_offset())));
  jmp(Constant(cont));

  bind(try_2_byte);
  comment("if (instance_size != size_type_array_2()) goto try_4_byte");
  cmpl(ebx, Constant(InstanceSize::size_type_array_2));
  jcc(not_equal, Constant(try_4_byte));
  leal(esi, Address(eax, esi, times_2, Constant(Array::base_offset())));
  leal(edi, Address(edx, edi, times_2, Constant(Array::base_offset())));
  shll(ecx, Constant(1));
  jmp(Constant(cont));

  bind(try_4_byte);
  comment("if (instance_size == size_type_array_4()) goto do_4_byte");
  cmpl(ebx, Constant(InstanceSize::size_type_array_4));
  jcc(equal, Constant(do_4_byte) );

  comment("if (instance_size != size_obj_array()) goto bailout");
  cmpl(ebx, Constant(InstanceSize::size_obj_array));
  jcc(not_equal, Constant(bailout));

  comment("if (dst < old_generation_end) goto bailout");
  cmpl( edx, Address( Constant( "_old_generation_end" ) ) );
  jcc( below, Constant(bailout));

  bind(do_4_byte);
  leal(esi, Address(eax, esi, times_4, Constant(Array::base_offset())));
  leal(edi, Address(edx, edi, times_4, Constant(Array::base_offset())));
  shll(ecx, Constant(2));

  bind(cont);
  comment("memmove(edi, esi, ecx);");
  pushl(ecx);
  pushl(esi);
  pushl(edi);
  call(Constant("memmove"));
  addl(esp, Constant(16));

  ret(Constant(5 * BytesPerStackElement));

  comment("Bail out to the general arraycopy implementation");
  bind(bailout);
  comment("pop method");
  popl(ebx);

  if (AddExternCUnderscore) {
    emit_instruction("jmp _interpreter_method_entry");
  } else {
    emit_instruction("jmp  interpreter_method_entry");
  }

  rom_linkable_entry_end(); // native_system_arraycopy_entry
}
void SourceAssembler::emit_instruction(const char* format, ...) {
  va_list arguments;
  va_start(arguments, format);
  emit_instruction(format, arguments);
  va_end(arguments);
}