struct program aggregate_ops(struct program *prog) { struct program aggregated_program; aggregated_program.ops = calloc(sizeof(struct brainfuck_op), INITIAL_PROGRAM_SIZE); aggregated_program.length = 0; aggregated_program.capacity = INITIAL_PROGRAM_SIZE; enum brainfuck_op_type last_seen_type = NOP; int count = 1; for (size_t i = 0; i < prog->length; i++) { if (prog->ops[i].type == last_seen_type) { // if the type we're looking at is the same as the last one, // increase the count and continue. if (last_seen_type == BRANCH_LEFT || last_seen_type == BRANCH_RIGHT) { // if the previous type was a branch and this one was as well, do not // combine them. struct brainfuck_op op; op.type = last_seen_type; op.op_value = 0; insert_op(&aggregated_program, op); continue; } OPS_AGGREGATED++; count++; } else { // if we're looking at a type that's not the same as the last type // that we observed, we need to "finish" off the last type. struct brainfuck_op op; if (last_seen_type != NOP) { op.type = last_seen_type; op.op_value = count; insert_op(&aggregated_program, op); } last_seen_type = prog->ops[i].type; count = 1; } } if (count != 1) { struct brainfuck_op op; op.type = last_seen_type; op.op_value = count; insert_op(&aggregated_program, op); } // stick a terminator onto the new program struct brainfuck_op exit_op; exit_op.type = EXIT; exit_op.op_value = 0; insert_op(&aggregated_program, exit_op); destroy_program(prog); return aggregated_program; }
struct program read_program(FILE *stream) { struct program scanned_program; scanned_program.ops = calloc(sizeof(struct brainfuck_op), INITIAL_PROGRAM_SIZE); scanned_program.length = 0; scanned_program.capacity = INITIAL_PROGRAM_SIZE; int scanned_char; while ((scanned_char = fgetc(stream)) != EOF) { struct brainfuck_op op; op.op_value = 0; switch (scanned_char) { case '+': op.type = PLUS; insert_op(&scanned_program, op); break; case '-': op.type = MINUS; insert_op(&scanned_program, op); break; case '<': op.type = SHIFT_LEFT; insert_op(&scanned_program, op); break; case '>': op.type = SHIFT_RIGHT; insert_op(&scanned_program, op); break; case '[': op.type = BRANCH_LEFT; insert_op(&scanned_program, op); break; case ']': op.type = BRANCH_RIGHT; insert_op(&scanned_program, op); break; case '.': op.type = OUTPUT; insert_op(&scanned_program, op); break; case ',': op.type = INPUT; insert_op(&scanned_program, op); break; } } struct brainfuck_op op; op.type = EXIT; op.op_value = 0; insert_op(&scanned_program, op); return scanned_program; }
void FpuStackAllocator::insert_copy(LIR_Opr from, LIR_Opr to) { int offset = tos_offset(from); LIR_Op1* fld = new LIR_Op1(lir_fld, LIR_OprFact::intConst(offset), LIR_OprFact::illegalOpr); insert_op(fld); sim()->push(fpu_num(to)); #ifndef PRODUCT if (TraceFPUStack) { tty->print("Inserted copy (%d -> %d) New state: ", fpu_num(from), fpu_num(to)); sim()->print(); tty->cr(); } #endif }
void FpuStackAllocator::insert_free(int offset) { // move stack slot to the top of stack and then pop it insert_exchange(offset); LIR_Op* fpop = new LIR_Op0(lir_fpop_raw); insert_op(fpop); sim()->pop(); #ifndef PRODUCT if (TraceFPUStack) { tty->print("Inserted pop New state: "); sim()->print(); tty->cr(); } #endif }
void FpuStackAllocator::insert_exchange(int offset) { if (offset > 0) { LIR_Op1* fxch_op = new LIR_Op1(lir_fxch, LIR_OprFact::intConst(offset), LIR_OprFact::illegalOpr); insert_op(fxch_op); sim()->swap(offset); #ifndef PRODUCT if (TraceFPUStack) { tty->print("Exchanged register: %d New state: ", sim()->get_slot(0)); sim()->print(); tty->cr(); } #endif } }