diff --git a/src/arm-codegen.c b/src/arm-codegen.c index c9b33aec..2bb70c69 100644 --- a/src/arm-codegen.c +++ b/src/arm-codegen.c @@ -80,7 +80,6 @@ void update_elf_offset(ph2_ir_t *ph2_ir) case OP_bit_or: case OP_bit_xor: case OP_negate: - case OP_log_and: case OP_bit_not: elf_offset += 4; return; @@ -119,6 +118,9 @@ void update_elf_offset(ph2_ir_t *ph2_ir) case OP_return: elf_offset += 24; return; + case OP_log_and: + elf_offset += 28; + return; default: printf("Unknown opcode\n"); abort(); @@ -439,8 +441,14 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir) emit(__mov_i(__EQ, rd, 1)); return; case OP_log_and: - /* FIXME: bad logical-and instruction */ - emit(__and_r(__AL, rd, rn, rm)); + /* TODO: short-circuit evaluation */ + emit(__teq(rn)); + emit(__mov_i(__NE, __r8, 1)); + emit(__mov_i(__EQ, __r8, 0)); + emit(__teq(rm)); + emit(__mov_i(__NE, rd, 1)); + emit(__mov_i(__EQ, rd, 0)); + emit(__and_r(__AL, rd, rd, __r8)); return; case OP_log_or: emit(__or_r(__AL, rd, rn, rm)); diff --git a/src/riscv-codegen.c b/src/riscv-codegen.c index 6d10d162..f7386d01 100644 --- a/src/riscv-codegen.c +++ b/src/riscv-codegen.c @@ -58,7 +58,6 @@ void update_elf_offset(ph2_ir_t *ph2_ir) case OP_bit_or: case OP_bit_xor: case OP_negate: - case OP_log_and: case OP_bit_not: elf_offset += 4; return; @@ -90,6 +89,7 @@ void update_elf_offset(ph2_ir_t *ph2_ir) case OP_branch: elf_offset += 20; return; + case OP_log_and: case OP_return: elf_offset += 24; return; @@ -413,8 +413,13 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir) emit(__xori(rd, rd, 1)); return; case OP_log_and: - /* FIXME: bad logical-and instruction */ - emit(__and(rd, rs1, rs2)); + /* TODO: short-circuit evaluation */ + emit(__xor(__t0, rs1, rs2)); + emit(__sub(rd, __t0, rs1)); + emit(__sub(__t0, __t0, rs2)); + emit(__sltu(rd, __zero, rd)); + emit(__sltu(__t0, __zero, __t0)); + emit(__and(rd, rd, __t0)); return; case OP_log_or: emit(__or(rd, rs1, rs2));