memcopy! and memset! intrinsics
This commit is contained in:
@@ -647,6 +647,24 @@ lower_compound_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instructi
|
||||
return append_recovery_value(state, expr.span, expr.type, expr.diagnostic)
|
||||
}
|
||||
|
||||
memory_region_element_type :: proc(value: types.Type, store: ^types.Store) -> types.Type {
|
||||
resolved := types.resolve_alias(value, store)
|
||||
item, ok := types.node(store, resolved)
|
||||
if !ok {
|
||||
return types.INVALID
|
||||
}
|
||||
if item.kind == .Slice {
|
||||
return item.child
|
||||
}
|
||||
if item.kind == .Pointer && !item.many {
|
||||
array, array_ok := types.node(store, types.resolve_alias(item.child, store))
|
||||
if array_ok && array.kind == .Array {
|
||||
return array.child
|
||||
}
|
||||
}
|
||||
return types.INVALID
|
||||
}
|
||||
|
||||
lower_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instruction_Id {
|
||||
stack := state.expr_stack
|
||||
state.expr_stack = nil
|
||||
@@ -691,6 +709,13 @@ lower_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instruction_Id {
|
||||
target=ir.INVALID_REF, a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION, diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
_ = pop(&stack)
|
||||
case .Undefined:
|
||||
last = append_instruction(state, ir.Instruction{
|
||||
op=.Poison, span=expr.span, type=expr.type,
|
||||
target=ir.INVALID_REF, a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
_ = pop(&stack)
|
||||
case .String, .Array, .Struct, .Range, .None, .Optional_Some, .Address, .Deref,
|
||||
.Index, .Slice, .Field, .Union_Tag, .Length, .Slice_Ptr, .Unwrap, .Orelse,
|
||||
.Try, .Catch, .Not, .Eq, .Ne, .Lt, .Le, .Gt, .Ge, .And, .Or:
|
||||
@@ -744,7 +769,7 @@ lower_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instruction_Id {
|
||||
append(&stack, Lower_Expr_Frame{expr=expr.left})
|
||||
case .Add, .Sub, .Mul, .Div, .Div_Trunc, .Div_Floor, .Div_Exact, .Div_Ceil,
|
||||
.Rem, .Mod, .Pointer_Add, .Bit_And, .Bit_Or, .Bit_Xor, .Shift_Left,
|
||||
.Shift_Right, .Shift_Left_Saturating:
|
||||
.Shift_Right, .Shift_Left_Saturating, .Mem_Copy, .Mem_Set:
|
||||
stack[frame_index].stage = 2
|
||||
append(&stack, Lower_Expr_Frame{expr=expr.left})
|
||||
case .Call:
|
||||
@@ -823,6 +848,7 @@ lower_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instruction_Id {
|
||||
}
|
||||
if frame.stage == 3 {
|
||||
op := ir.Opcode.Add_Checked
|
||||
result_type := expr.type
|
||||
#partial switch expr.kind {
|
||||
case .Sub: op = .Sub_Checked
|
||||
case .Mul: op = .Mul_Checked
|
||||
@@ -840,10 +866,16 @@ lower_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instruction_Id {
|
||||
case .Shift_Left: op = .Shift_Left
|
||||
case .Shift_Right: op = .Shift_Right
|
||||
case .Shift_Left_Saturating: op = .Shift_Left_Saturating
|
||||
case .Mem_Copy:
|
||||
op = .Mem_Copy
|
||||
result_type = memory_region_element_type(state.hir_module.exprs[expr.left].type, &state.hir_module.types)
|
||||
case .Mem_Set:
|
||||
op = .Mem_Set
|
||||
result_type = memory_region_element_type(state.hir_module.exprs[expr.left].type, &state.hir_module.types)
|
||||
}
|
||||
last = append_instruction(state, ir.Instruction{
|
||||
op=op,
|
||||
span=expr.span, type=expr.type, target=ir.INVALID_REF,
|
||||
span=expr.span, type=result_type, target=ir.INVALID_REF,
|
||||
a=frame.left, b=last, diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
_ = pop(&stack)
|
||||
|
||||
Reference in New Issue
Block a user