Example #1
0
File: darm.c Project: rkr090/darm
static int _append_imm(char *arg, uint32_t imm)
{
    const char *start = arg;
    if(imm > 0x1000) {
        *arg++ = '0';
        *arg++ = 'x';
        arg += _utoa(imm, arg, 16);
    }
    else {
        arg += _utoa(imm, arg, 10);
    }
    return arg - start;
}
Example #2
0
File: fmt.c Project: j4cbo/minilib
static void _fmtp(struct fmtctx *ctx, char c, va_list *va) {
	void *p = va_arg(*va, void *);
	(void)c;
	ctx->state |= ST_ZEROPAD;
	PACKWID(ctx, sizeof(void*) * 2);
	_utoa(ctx, 16, (unsigned long)p);
}
Example #3
0
File: fmt.c Project: j4cbo/minilib
static void _fmtd(struct fmtctx *ctx, char c, va_list *va) {
	int n = va_arg(*va, int);
	(void)c;
	if (n < 0) {
		ctx->state |= ST_NEGATIVE;
		n = -n;
	}
	_utoa(ctx, 10, n);
}
Example #4
0
File: integer.c Project: AxFab/axc
char *itoa (int value, char *str, int base)
{
  char *ptr = str;

  if (base == 10 && value < 0) {
    *(str++) = '-';
    value = -value;
  }

  _utoa (value, str, base, _utoa_digits);
  return ptr;
}
Example #5
0
/*
 * See header for comments
 */
void itoae(uint8_t *p_buf, int value, int dpp, int min_len, uint8_t fill_char)
{
    //-- if the value is negative, put the minus sign at the beginning,
    //   and make the value positive
    if(value < 0) {
        *p_buf++ = '-';
        value = -value;
    }

    //-- perform "regular" itoa call
    _utoa(p_buf, value, 10);
    size_t len = strlen(p_buf);


    //-- if we need to add leading zeros for decimal point, do it
    len = _add_leading(p_buf, len, (dpp + 1), '0');

    //-- if we need to fill chars in the beginning, do it
    len = _add_leading(p_buf, len, min_len, fill_char);

    //-- if we need to put decimal point, do this
    if (dpp > 0){
        int i;
        for (i = 0; i < (dpp + 1/*null-terminate*/); i++){
            p_buf[len - i + 1] = p_buf[len - i];
        }
        p_buf[len - dpp] = '.';

        //-- since we've added a dot, length has just increased by 1
        len += 1;

        //-- put zeros around dot if necessary
        for (i = len - dpp - 1 - 1; i < len; i++){
            if (p_buf[i] == fill_char){
                p_buf[i] = '0';
            } else if (p_buf[i] != '.'){
                break;
            }
        }
    }
}
Example #6
0
File: fmt.c Project: j4cbo/minilib
static void _fmtu(struct fmtctx *ctx, char c, va_list *va) {
	unsigned int n = va_arg(*va, unsigned int);
	_utoa(ctx, c == 'u' ? 10 : (c == 'o' ? 8 : 16), n);
}
Example #7
0
File: darm.c Project: rkr090/darm
int darm_str(const darm_t *d, darm_str_t *str)
{
    if(d->instr == I_INVLD || d->instr >= ARRAYSIZE(darm_mnemonics)) {
        return -1;
    }

    // the format string index
    uint32_t idx = 0;

    // the offset in the format string
    uint32_t off = 0;

    // argument index
    uint32_t arg = 0;

    // pointers to the arguments
    char *args[] = {
        str->arg[0], str->arg[1], str->arg[2],
        str->arg[3], str->arg[4], str->arg[5],
    };

    // ptr to the output mnemonic
    char *mnemonic = str->mnemonic;
    APPEND(mnemonic, darm_mnemonic_name(d->instr));

    char *shift = str->shift;

    const char **ptrs = armv7_format_strings[d->instr];
    if(ptrs[0] == NULL) return -1;

    for (char ch; (ch = ptrs[idx][off]) != 0; off++) {
        switch (ch) {
        case 's':
            if(d->S == B_SET) {
                *mnemonic++ = 'S';
            }
            continue;

        case 'c':
            APPEND(mnemonic, darm_condition_name(d->cond, 1));
            continue;

        case 'd':
            if(d->Rd == R_INVLD) break;
            APPEND(args[arg], darm_register_name(d->Rd));
            arg++;
            continue;

        case 'n':
            if(d->Rn == R_INVLD) break;
            APPEND(args[arg], darm_register_name(d->Rn));
            arg++;
            continue;

        case 'm':
            if(d->Rm == R_INVLD) break;
            APPEND(args[arg], darm_register_name(d->Rm));
            arg++;
            continue;

        case 'a':
            if(d->Ra == R_INVLD) break;
            APPEND(args[arg], darm_register_name(d->Ra));
            arg++;
            continue;

        case 't':
            if(d->Rt == R_INVLD) break;
            APPEND(args[arg], darm_register_name(d->Rt));
            arg++;
            continue;

        case '2':
            // first check if Rt2 is actually set
            if(d->Rt2 != R_INVLD) {
                APPEND(args[arg], darm_register_name(d->Rt2));
                arg++;
                continue;
            }
            // for some instructions, Rt2 = Rt + 1
            else if(d->Rt != R_INVLD) {
                APPEND(args[arg], darm_register_name(d->Rt + 1));
                arg++;
                continue;
            }
            break;

        case 'h':
            if(d->RdHi == R_INVLD) break;
            APPEND(args[arg], darm_register_name(d->RdHi));
            arg++;
            continue;

        case 'l':
            if(d->RdLo == R_INVLD) break;
            APPEND(args[arg], darm_register_name(d->RdLo));
            arg++;
            continue;

        case 'i':
            // check if an immediate has been set
            if(d->I != B_SET) break;

            *args[arg]++ = '#';
            args[arg] += _append_imm(args[arg], d->imm);
            arg++;
            continue;

        case 'S':
            // is there even a shift?
            if(d->shift_type == S_INVLD) continue;

            if(d->P == B_SET) {
                // we're still inside the memory address
                shift = args[arg] - 1;
                *shift++ = ',';
                *shift++ = ' ';
            }

            if(d->Rs == R_INVLD) {
                const char *type; uint32_t imm;
                if(darm_immshift_decode(d, &type, &imm) == 0) {
                    switch (d->instr) {
                    case I_LSL: case I_LSR: case I_ASR:
                    case I_ROR: case I_RRX:
                        break;

                    default:
                        APPEND(shift, type);
                        *shift++ = ' ';
                    }
                    *shift++ = '#';
                    shift += _utoa(imm, shift, 10);
                }
                else if(d->P == B_SET) {
                    // we're still in the memory address, but there was
                    // no shift, so we have to revert the shift pointer so
                    // it will write a closing bracket again
                    shift -= 2;
                }
            }
            else {
                APPEND(shift, darm_shift_type_name(d->shift_type));
                *shift++ = ' ';
                APPEND(shift, darm_register_name(d->Rs));
            }

            if(d->P == B_SET) {
                // close the memory address
                *shift++ = ']';

                // reset shift
                args[arg] = shift;
                shift = str->shift;
            }
            continue;

        case '!':
            if(d->W == B_SET) {
                *args[arg-1]++ = '!';
            }
            continue;

        case 'e':
            args[arg] += _utoa(d->E, args[arg], 10);
            continue;

        case 'x':
            if(d->M == B_SET) {
                *mnemonic++ = 'x';
            }
            continue;

        case 'X':
            // if the flags are not set, then this instruction doesn't take
            // the (B|T)(B|T) postfix
            if(d->N == B_INVLD || d->M == B_INVLD) break;

            *mnemonic++ = d->N == B_SET ? 'T' : 'B';
            *mnemonic++ = d->M == B_SET ? 'T' : 'B';
            continue;

        case 'R':
            if(d->R == B_SET) {
                *mnemonic++ = 'R';
            }
            continue;

        case 'T':
            APPEND(mnemonic, d->T == B_SET ? "TB" : "BT");
            continue;

        case 'r':
            if(d->reglist != 0) {
                args[arg] += darm_reglist(d->reglist, args[arg]);
            }
            else {
                *args[arg]++ = '{';
                APPEND(args[arg], darm_register_name(d->Rt));
                *args[arg]++ = '}';
            }
            continue;

        case 'L':
            *args[arg]++ = '#';
            args[arg] += _utoa(d->lsb, args[arg], 10);
            arg++;
            continue;

        case 'w':
            *args[arg]++ = '#';
            args[arg] += _utoa(d->width, args[arg], 10);
            arg++;
            continue;

        case 'o':
            *args[arg]++ = '#';
            args[arg] += _utoa(d->option, args[arg], 10);
            arg++;
            continue;

        case 'B':
            *args[arg]++ = '[';
            APPEND(args[arg], darm_register_name(d->Rn));

            // if post-indexed or the index is not even set, then we close
            // the memory address
            if(d->P != B_SET) {
                *args[arg++]++ = ']';
            }
            else {
                *args[arg]++ = ',';
                *args[arg]++ = ' ';
            }
            continue;

        case 'O':
            // if the Rm operand is set, then this is about the Rm operand,
            // otherwise it's about the immediate
            if(d->Rm != R_INVLD) {

                // negative offset
                if(d->U == B_UNSET) {
                    *args[arg]++ = '-';
                }

                APPEND(args[arg], darm_register_name(d->Rm));

                // if post-indexed this was a stand-alone operator one
                if(d->P == B_UNSET) {
                    arg++;
                }
            }
            // if there's an immediate, append it
            else if(d->imm != 0) {
                // negative offset?
                APPEND(args[arg], d->U == B_UNSET ? "#-" : "#");
                args[arg] += _append_imm(args[arg], d->imm);
            }
            else {
                // there's no immediate, so we have to remove the ", " which
                // was introduced by the base register of the memory address
                args[arg] -= 2;
            }

            // if pre-indexed, close the memory address, but don't increase
            // arg so we can alter it in the shift handler
            if(d->P == B_SET) {
                *args[arg]++ = ']';

                // if pre-indexed and write-back, then add an exclamation mark
                if(d->W == B_SET) {
                    *args[arg]++ = '!';
                }
            }
            continue;

        case 'b':
            // BLX first checks for branch and only then for the conditional
            // version which takes the Rm as operand, so let's see if the
            // branch stuff has been initialized yet
            if(d->instr == I_BLX && d->H == B_INVLD) break;

            // check whether the immediate is negative
            int32_t imm = d->imm;
            if(imm < 0 && imm >= -0x1000) {
                APPEND(args[arg], "#+-");
                imm = -imm;
            }
            else if(d->U == B_UNSET) {
                APPEND(args[arg], "#+-");
            }
            else {
                APPEND(args[arg], "#+");
            }
            args[arg] += _append_imm(args[arg], imm);
            continue;

        case 'M':
            *args[arg]++ = '[';
            APPEND(args[arg], darm_register_name(d->Rn));

            // if the Rm operand is defined, then we use that optionally with
            // a shift, otherwise there might be an immediate value as offset
            if(d->Rm != R_INVLD) {
                APPEND(args[arg], ", ");
                APPEND(args[arg], darm_register_name(d->Rm));

                const char *type; uint32_t imm;
                if(darm_immshift_decode(d, &type, &imm) == 0) {
                    APPEND(args[arg], ", ");
                    APPEND(args[arg], type);
                    APPEND(args[arg], " #");
                    args[arg] += _utoa(imm, args[arg], 10);
                }
            }
            else if(d->imm != 0) {
                APPEND(args[arg], ", ");

                // negative offset?
                APPEND(args[arg], d->U == B_UNSET ? "#-" : "#");
                args[arg] += _append_imm(args[arg], d->imm);
            }

            *args[arg]++ = ']';

            // if index is true and write-back is true, then we add an
            // exclamation mark
            if(d->P == B_SET && d->W == B_SET) {
                *args[arg]++ = '!';
            }
            continue;

        case 'A':
            if(d->rotate != 0) {
                APPEND(args[arg], "ROR #");
                args[arg] += _utoa(d->rotate, args[arg], 10);
            }
            continue;

        case 'C':
            args[arg] += _utoa(d->coproc, args[arg], 10);
            arg++;
            continue;

        case 'p':
            args[arg] += _utoa(d->opc1, args[arg], 10);
            arg++;
            continue;

        case 'P':
            args[arg] += _utoa(d->opc2, args[arg], 10);
            arg++;
            continue;

        case 'N':
            APPEND(args[arg], "cr");
            args[arg] += _utoa(d->CRn, args[arg], 10);
            arg++;
            continue;

        case 'J':
            APPEND(args[arg], "cr");
            args[arg] += _utoa(d->CRm, args[arg], 10);
            arg++;
            continue;

        case 'I':
            APPEND(args[arg], "cr");
            args[arg] += _utoa(d->CRd, args[arg], 10);
            arg++;
            continue;

        default:
            return -1;
        }

        if(ptrs[++idx] == NULL || idx == 3) return -1;
        off--;
    }

    *mnemonic = *shift = 0;
    *args[0] = *args[1] = *args[2] = *args[3] = *args[4] = *args[5] = 0;

    char *instr = str->total;
    APPEND(instr, str->mnemonic);

    for (int i = 0; i < 6 && args[i] != str->arg[i]; i++) {
        if(i != 0) *instr++ = ',';
        *instr++ = ' ';
        APPEND(instr, str->arg[i]);
    }

    if(shift != str->shift) {
        *instr++ = ',';
        *instr++ = ' ';
        APPEND(instr, str->shift);
    }

    *instr = 0;
    return 0;
}