Branch data Line data Source code
1 : : /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2 : : *
3 : : * Copyright 2008-2016 Freescale Semiconductor Inc.
4 : : * Copyright 2016,2019 NXP
5 : : */
6 : :
7 : : #ifndef __RTA_JUMP_CMD_H__
8 : : #define __RTA_JUMP_CMD_H__
9 : :
10 : : static const uint32_t jump_test_cond[][2] = {
11 : : { NIFP, JUMP_COND_NIFP },
12 : : { NIP, JUMP_COND_NIP },
13 : : { NOP, JUMP_COND_NOP },
14 : : { NCP, JUMP_COND_NCP },
15 : : { CALM, JUMP_COND_CALM },
16 : : { SELF, JUMP_COND_SELF },
17 : : { SHRD, JUMP_COND_SHRD },
18 : : { JQP, JUMP_COND_JQP },
19 : : { MATH_Z, JUMP_COND_MATH_Z },
20 : : { MATH_N, JUMP_COND_MATH_N },
21 : : { MATH_NV, JUMP_COND_MATH_NV },
22 : : { MATH_C, JUMP_COND_MATH_C },
23 : : { PK_0, JUMP_COND_PK_0 },
24 : : { PK_GCD_1, JUMP_COND_PK_GCD_1 },
25 : : { PK_PRIME, JUMP_COND_PK_PRIME },
26 : : { CLASS1, JUMP_CLASS_CLASS1 },
27 : : { CLASS2, JUMP_CLASS_CLASS2 },
28 : : { BOTH, JUMP_CLASS_BOTH }
29 : : };
30 : :
31 : : static const uint32_t jump_test_math_cond[][2] = {
32 : : { MATH_Z, JUMP_COND_MATH_Z },
33 : : { MATH_N, JUMP_COND_MATH_N },
34 : : { MATH_NV, JUMP_COND_MATH_NV },
35 : : { MATH_C, JUMP_COND_MATH_C }
36 : : };
37 : :
38 : : static const uint32_t jump_src_dst[][2] = {
39 : : { MATH0, JUMP_SRC_DST_MATH0 },
40 : : { MATH1, JUMP_SRC_DST_MATH1 },
41 : : { MATH2, JUMP_SRC_DST_MATH2 },
42 : : { MATH3, JUMP_SRC_DST_MATH3 },
43 : : { DPOVRD, JUMP_SRC_DST_DPOVRD },
44 : : { SEQINSZ, JUMP_SRC_DST_SEQINLEN },
45 : : { SEQOUTSZ, JUMP_SRC_DST_SEQOUTLEN },
46 : : { VSEQINSZ, JUMP_SRC_DST_VARSEQINLEN },
47 : : { VSEQOUTSZ, JUMP_SRC_DST_VARSEQOUTLEN }
48 : : };
49 : :
50 : : static inline int
51 : 0 : rta_jump(struct program *program, uint64_t address,
52 : : enum rta_jump_type jump_type,
53 : : enum rta_jump_cond test_type,
54 : : uint32_t test_condition, uint32_t src_dst)
55 : : {
56 : : uint32_t opcode = CMD_JUMP;
57 [ # # ]: 0 : unsigned int start_pc = program->current_pc;
58 : : int ret = -EINVAL;
59 : :
60 : : switch (jump_type) {
61 : : case (LOCAL_JUMP):
62 : : /*
63 : : * opcode |= JUMP_TYPE_LOCAL;
64 : : * JUMP_TYPE_LOCAL is 0
65 : : */
66 : : break;
67 : : case (HALT):
68 : : opcode |= JUMP_TYPE_HALT;
69 : : break;
70 : : case (HALT_STATUS):
71 : : opcode |= JUMP_TYPE_HALT_USER;
72 : : break;
73 : : case (FAR_JUMP):
74 : : opcode |= JUMP_TYPE_NONLOCAL;
75 : : break;
76 : : case (GOSUB):
77 : : opcode |= JUMP_TYPE_GOSUB;
78 : : break;
79 : : case (RETURN):
80 : : opcode |= JUMP_TYPE_RETURN;
81 : : break;
82 : : case (LOCAL_JUMP_INC):
83 : : opcode |= JUMP_TYPE_LOCAL_INC;
84 : : break;
85 : : case (LOCAL_JUMP_DEC):
86 : : opcode |= JUMP_TYPE_LOCAL_DEC;
87 : : break;
88 : 0 : default:
89 : 0 : pr_err("JUMP: Invalid jump type. SEC Program Line: %d\n",
90 : : program->current_pc);
91 : 0 : goto err;
92 : : }
93 : :
94 [ # # # # : 0 : switch (test_type) {
# ]
95 : : case (ALL_TRUE):
96 : : /*
97 : : * opcode |= JUMP_TEST_ALL;
98 : : * JUMP_TEST_ALL is 0
99 : : */
100 : : break;
101 : 0 : case (ALL_FALSE):
102 : 0 : opcode |= JUMP_TEST_INVALL;
103 : 0 : break;
104 : 0 : case (ANY_TRUE):
105 : 0 : opcode |= JUMP_TEST_ANY;
106 : 0 : break;
107 : 0 : case (ANY_FALSE):
108 : 0 : opcode |= JUMP_TEST_INVANY;
109 : 0 : break;
110 : 0 : default:
111 : 0 : pr_err("JUMP: test type not supported. SEC Program Line: %d\n",
112 : : program->current_pc);
113 : 0 : goto err;
114 : : }
115 : :
116 : : /* write test condition field */
117 [ # # ]: 0 : if ((jump_type != LOCAL_JUMP_INC) && (jump_type != LOCAL_JUMP_DEC)) {
118 : : __rta_map_flags(test_condition, jump_test_cond,
119 : : ARRAY_SIZE(jump_test_cond), &opcode);
120 : : } else {
121 : : uint32_t val = 0;
122 : :
123 : : ret = __rta_map_opcode(src_dst, jump_src_dst,
124 : : ARRAY_SIZE(jump_src_dst), &val);
125 : : if (ret < 0) {
126 : 0 : pr_err("JUMP_INCDEC: SRC_DST not supported. SEC PC: %d; Instr: %d\n",
127 : : program->current_pc,
128 : : program->current_instruction);
129 : 0 : goto err;
130 : : }
131 : 0 : opcode |= val;
132 : :
133 : : __rta_map_flags(test_condition, jump_test_math_cond,
134 : : ARRAY_SIZE(jump_test_math_cond), &opcode);
135 : : }
136 : :
137 : : /* write local offset field for local jumps and user-defined halt */
138 [ # # ]: 0 : if ((jump_type == LOCAL_JUMP) || (jump_type == LOCAL_JUMP_INC) ||
139 [ # # # # ]: 0 : (jump_type == LOCAL_JUMP_DEC) || (jump_type == GOSUB) ||
140 : : (jump_type == HALT_STATUS))
141 : 0 : opcode |= (uint32_t)(address & JUMP_OFFSET_MASK);
142 : :
143 : 0 : __rta_out32(program, opcode);
144 : 0 : program->current_instruction++;
145 : :
146 [ # # ]: 0 : if (jump_type == FAR_JUMP)
147 : 0 : __rta_out64(program, program->ps, address);
148 : :
149 : 0 : return (int)start_pc;
150 : :
151 : 0 : err:
152 : 0 : program->first_error_pc = start_pc;
153 : 0 : program->current_instruction++;
154 : 0 : return ret;
155 : : }
156 : :
157 : : #endif /* __RTA_JUMP_CMD_H__ */
|