io interface (first pass)
This commit is contained in:
+19
-9
@@ -1648,18 +1648,23 @@ emit_instruction_stream :: proc(
|
||||
)
|
||||
fmt.sbprintf(&emitter.builder, ", %s zeroinitializer\n", type_name)
|
||||
case .Scalar_Cast:
|
||||
if !valid_instruction(instructions, instruction.a) ||
|
||||
!types.is_concrete_scalar(instructions[instruction.a].type) ||
|
||||
!types.is_concrete_scalar(instruction.type) ||
|
||||
types.is_bool(instructions[instruction.a].type) ||
|
||||
types.is_bool(instruction.type) {
|
||||
if !valid_instruction(instructions, instruction.a) {
|
||||
emit_recovery_value(emitter, instruction_index, instruction, "invalid scalar cast operand")
|
||||
continue
|
||||
}
|
||||
from_type := instructions[instruction.a].type
|
||||
from_bits := types.bits(from_type, emitter.module.target)
|
||||
from_repr := types.runtime_representation(from_type, &emitter.module.types)
|
||||
from_item, from_item_ok := types.node(&emitter.module.types, from_type)
|
||||
explicit_enum := from_item_ok && from_item.kind == .Enum && from_item.explicit_backing
|
||||
valid_from := (types.is_concrete_scalar(from_type) || explicit_enum) &&
|
||||
types.is_concrete_scalar(from_repr) && !types.is_bool(from_repr)
|
||||
if !valid_from || !types.is_concrete_scalar(instruction.type) || types.is_bool(instruction.type) {
|
||||
emit_recovery_value(emitter, instruction_index, instruction, "invalid scalar cast operand")
|
||||
continue
|
||||
}
|
||||
from_bits := types.bits(from_repr, emitter.module.target)
|
||||
to_bits := types.bits(instruction.type, emitter.module.target)
|
||||
from_float := types.is_float(from_type, emitter.module.target)
|
||||
from_float := types.is_float(from_repr, emitter.module.target)
|
||||
to_float := types.is_float(instruction.type, emitter.module.target)
|
||||
if types.equal(from_type, instruction.type) || from_bits == to_bits && from_float == to_float {
|
||||
type_name := llvm_type(instruction.type, &emitter.module.types)
|
||||
@@ -1675,11 +1680,11 @@ emit_instruction_stream :: proc(
|
||||
case from_float && to_float:
|
||||
operation = "fpext" if from_bits < to_bits else "fptrunc"
|
||||
case !from_float && !to_float:
|
||||
operation = "trunc" if from_bits > to_bits else ("sext" if types.is_signed(from_type, emitter.module.target) else "zext")
|
||||
operation = "trunc" if from_bits > to_bits else ("sext" if types.is_signed(from_repr, emitter.module.target) else "zext")
|
||||
case from_float:
|
||||
operation = "fptosi" if types.is_signed(instruction.type, emitter.module.target) else "fptoui"
|
||||
case:
|
||||
operation = "sitofp" if types.is_signed(from_type, emitter.module.target) else "uitofp"
|
||||
operation = "sitofp" if types.is_signed(from_repr, emitter.module.target) else "uitofp"
|
||||
}
|
||||
fmt.sbprintf(&emitter.builder, " %%v%d = %s %s ", instruction_index, operation, llvm_type(from_type, &emitter.module.types))
|
||||
write_operand(&emitter.builder, instructions, instruction.a, from_type, &emitter.module.types)
|
||||
@@ -2357,6 +2362,11 @@ emit_constructor :: proc(emitter: ^Emitter) {
|
||||
|
||||
emit_functions :: proc(emitter: ^Emitter) {
|
||||
for function, function_index in emitter.module.functions {
|
||||
// bro.trap already declares libc write. A demanded std/io binding shares
|
||||
// that declaration instead of emitting an LLVM redefinition.
|
||||
if function.implementation == .Declaration && function.link_name == "write" {
|
||||
continue
|
||||
}
|
||||
if function.implementation == .Declaration {
|
||||
duplicate := false
|
||||
for previous in emitter.module.functions[:function_index] {
|
||||
|
||||
Reference in New Issue
Block a user