Skip to content

Commit a9b95be

Browse files
author
Mihai Budiu
authored
Insert cast for signed slices; fixes #2090 (#2091)
* Insert cast for signed slices; fixes #2090
1 parent 2fca832 commit a9b95be

13 files changed

+595
-2
lines changed

midend/expandLookahead.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ const IR::Expression* DoExpandLookahead::expand(
5656
} else if (type->is<IR::Type_Bits>() || type->is<IR::Type_Boolean>()) {
5757
unsigned size = type->width_bits();
5858
BUG_CHECK(size > 0, "%1%: unexpected size %2%", type, size);
59-
auto expression = new IR::Slice(base->clone(), *offset - 1, *offset - size);
59+
const IR::Expression* expression =
60+
new IR::Slice(base->clone(), *offset - 1, *offset - size);
61+
auto tb = type->to<IR::Type_Bits>();
62+
if (!tb || tb->isSigned)
63+
expression = new IR::Cast(type, expression);
6064
*offset -= size;
6165
return expression;
6266
} else {

testdata/p4_16_samples/issue2090.p4

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
Copyright 2013-present Barefoot Networks, Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include <core.p4>
18+
19+
#include "spec-ex09.p4"
20+
21+
struct Tcp_option_sack_top
22+
{
23+
int<8> kind;
24+
bit<8> length;
25+
bool f;
26+
bit<7> padding;
27+
}
28+
parser Tcp_option_parser(packet_in b,
29+
out Tcp_option_stack vec)
30+
{
31+
state start {
32+
transition select(b.lookahead<bit<8>>()) {
33+
8w0x0 : parse_tcp_option_end;
34+
8w0x1 : parse_tcp_option_nop;
35+
8w0x2 : parse_tcp_option_ss;
36+
8w0x3 : parse_tcp_option_s;
37+
8w0x5 : parse_tcp_option_sack;
38+
}
39+
}
40+
state parse_tcp_option_end {
41+
b.extract(vec.next.end);
42+
transition accept;
43+
}
44+
state parse_tcp_option_nop {
45+
b.extract(vec.next.nop);
46+
transition start;
47+
}
48+
state parse_tcp_option_ss {
49+
b.extract(vec.next.ss);
50+
transition start;
51+
}
52+
state parse_tcp_option_s {
53+
b.extract(vec.next.s);
54+
transition start;
55+
}
56+
state parse_tcp_option_sack {
57+
b.extract(vec.next.sack,
58+
(bit<32>)(8 * (b.lookahead<Tcp_option_sack_top>().length) -
59+
16));
60+
transition start;
61+
}
62+
}
63+
64+
parser pr<H>(packet_in b, out H h);
65+
package top<H>(pr<H> p);
66+
67+
top(Tcp_option_parser()) main;

testdata/p4_16_samples/spec-ex19.p4

+5
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,8 @@ parser Tcp_option_parser(packet_in b,
5858
transition start;
5959
}
6060
}
61+
62+
parser pr<H>(packet_in b, out H h);
63+
package top<H>(pr<H> p);
64+
65+
top(Tcp_option_parser()) main;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include <core.p4>
2+
3+
header Mpls_h {
4+
bit<20> label;
5+
bit<3> tc;
6+
bit<1> bos;
7+
bit<8> ttl;
8+
}
9+
10+
control p() {
11+
apply {
12+
Mpls_h[10] mpls_vec;
13+
}
14+
}
15+
16+
header Tcp_option_end_h {
17+
bit<8> kind;
18+
}
19+
20+
header Tcp_option_nop_h {
21+
bit<8> kind;
22+
}
23+
24+
header Tcp_option_ss_h {
25+
bit<8> kind;
26+
bit<32> maxSegmentSize;
27+
}
28+
29+
header Tcp_option_s_h {
30+
bit<8> kind;
31+
bit<24> scale;
32+
}
33+
34+
header Tcp_option_sack_h {
35+
bit<8> kind;
36+
bit<8> length;
37+
varbit<256> sack;
38+
}
39+
40+
header_union Tcp_option_h {
41+
Tcp_option_end_h end;
42+
Tcp_option_nop_h nop;
43+
Tcp_option_ss_h ss;
44+
Tcp_option_s_h s;
45+
Tcp_option_sack_h sack;
46+
}
47+
48+
typedef Tcp_option_h[10] Tcp_option_stack;
49+
struct Tcp_option_sack_top {
50+
int<8> kind;
51+
bit<8> length;
52+
bool f;
53+
bit<7> padding;
54+
}
55+
56+
parser Tcp_option_parser(packet_in b, out Tcp_option_stack vec) {
57+
state start {
58+
transition select(b.lookahead<bit<8>>()) {
59+
8w0x0: parse_tcp_option_end;
60+
8w0x1: parse_tcp_option_nop;
61+
8w0x2: parse_tcp_option_ss;
62+
8w0x3: parse_tcp_option_s;
63+
8w0x5: parse_tcp_option_sack;
64+
}
65+
}
66+
state parse_tcp_option_end {
67+
b.extract<Tcp_option_end_h>(vec.next.end);
68+
transition accept;
69+
}
70+
state parse_tcp_option_nop {
71+
b.extract<Tcp_option_nop_h>(vec.next.nop);
72+
transition start;
73+
}
74+
state parse_tcp_option_ss {
75+
b.extract<Tcp_option_ss_h>(vec.next.ss);
76+
transition start;
77+
}
78+
state parse_tcp_option_s {
79+
b.extract<Tcp_option_s_h>(vec.next.s);
80+
transition start;
81+
}
82+
state parse_tcp_option_sack {
83+
b.extract<Tcp_option_sack_h>(vec.next.sack, (bit<32>)(((b.lookahead<Tcp_option_sack_top>()).length << 3) + 8w240));
84+
transition start;
85+
}
86+
}
87+
88+
parser pr<H>(packet_in b, out H h);
89+
package top<H>(pr<H> p);
90+
top<Tcp_option_h[10]>(Tcp_option_parser()) main;
91+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include <core.p4>
2+
3+
header Mpls_h {
4+
bit<20> label;
5+
bit<3> tc;
6+
bit<1> bos;
7+
bit<8> ttl;
8+
}
9+
10+
header Tcp_option_end_h {
11+
bit<8> kind;
12+
}
13+
14+
header Tcp_option_nop_h {
15+
bit<8> kind;
16+
}
17+
18+
header Tcp_option_ss_h {
19+
bit<8> kind;
20+
bit<32> maxSegmentSize;
21+
}
22+
23+
header Tcp_option_s_h {
24+
bit<8> kind;
25+
bit<24> scale;
26+
}
27+
28+
header Tcp_option_sack_h {
29+
bit<8> kind;
30+
bit<8> length;
31+
varbit<256> sack;
32+
}
33+
34+
header_union Tcp_option_h {
35+
Tcp_option_end_h end;
36+
Tcp_option_nop_h nop;
37+
Tcp_option_ss_h ss;
38+
Tcp_option_s_h s;
39+
Tcp_option_sack_h sack;
40+
}
41+
42+
typedef Tcp_option_h[10] Tcp_option_stack;
43+
struct Tcp_option_sack_top {
44+
int<8> kind;
45+
bit<8> length;
46+
bool f;
47+
bit<7> padding;
48+
}
49+
50+
parser Tcp_option_parser(packet_in b, out Tcp_option_stack vec) {
51+
bit<8> tmp;
52+
Tcp_option_sack_top tmp_0;
53+
bit<8> tmp_1;
54+
bit<8> tmp_2;
55+
bit<32> tmp_3;
56+
state start {
57+
tmp = b.lookahead<bit<8>>();
58+
transition select(tmp) {
59+
8w0x0: parse_tcp_option_end;
60+
8w0x1: parse_tcp_option_nop;
61+
8w0x2: parse_tcp_option_ss;
62+
8w0x3: parse_tcp_option_s;
63+
8w0x5: parse_tcp_option_sack;
64+
}
65+
}
66+
state parse_tcp_option_end {
67+
b.extract<Tcp_option_end_h>(vec.next.end);
68+
transition accept;
69+
}
70+
state parse_tcp_option_nop {
71+
b.extract<Tcp_option_nop_h>(vec.next.nop);
72+
transition start;
73+
}
74+
state parse_tcp_option_ss {
75+
b.extract<Tcp_option_ss_h>(vec.next.ss);
76+
transition start;
77+
}
78+
state parse_tcp_option_s {
79+
b.extract<Tcp_option_s_h>(vec.next.s);
80+
transition start;
81+
}
82+
state parse_tcp_option_sack {
83+
tmp_0 = b.lookahead<Tcp_option_sack_top>();
84+
tmp_1 = tmp_0.length << 3;
85+
tmp_2 = tmp_1 + 8w240;
86+
tmp_3 = (bit<32>)tmp_2;
87+
b.extract<Tcp_option_sack_h>(vec.next.sack, tmp_3);
88+
transition start;
89+
}
90+
}
91+
92+
parser pr<H>(packet_in b, out H h);
93+
package top<H>(pr<H> p);
94+
top<Tcp_option_h[10]>(Tcp_option_parser()) main;
95+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include <core.p4>
2+
3+
header Mpls_h {
4+
bit<20> label;
5+
bit<3> tc;
6+
bit<1> bos;
7+
bit<8> ttl;
8+
}
9+
10+
header Tcp_option_end_h {
11+
bit<8> kind;
12+
}
13+
14+
header Tcp_option_nop_h {
15+
bit<8> kind;
16+
}
17+
18+
header Tcp_option_ss_h {
19+
bit<8> kind;
20+
bit<32> maxSegmentSize;
21+
}
22+
23+
header Tcp_option_s_h {
24+
bit<8> kind;
25+
bit<24> scale;
26+
}
27+
28+
header Tcp_option_sack_h {
29+
bit<8> kind;
30+
bit<8> length;
31+
varbit<256> sack;
32+
}
33+
34+
header_union Tcp_option_h {
35+
Tcp_option_end_h end;
36+
Tcp_option_nop_h nop;
37+
Tcp_option_ss_h ss;
38+
Tcp_option_s_h s;
39+
Tcp_option_sack_h sack;
40+
}
41+
42+
typedef Tcp_option_h[10] Tcp_option_stack;
43+
struct Tcp_option_sack_top {
44+
int<8> kind;
45+
bit<8> length;
46+
bool f;
47+
bit<7> padding;
48+
}
49+
50+
parser Tcp_option_parser(packet_in b, out Tcp_option_stack vec) {
51+
bit<8> tmp;
52+
bit<24> tmp_4;
53+
state start {
54+
tmp = b.lookahead<bit<8>>();
55+
transition select(tmp) {
56+
8w0x0: parse_tcp_option_end;
57+
8w0x1: parse_tcp_option_nop;
58+
8w0x2: parse_tcp_option_ss;
59+
8w0x3: parse_tcp_option_s;
60+
8w0x5: parse_tcp_option_sack;
61+
default: noMatch;
62+
}
63+
}
64+
state parse_tcp_option_end {
65+
b.extract<Tcp_option_end_h>(vec.next.end);
66+
transition accept;
67+
}
68+
state parse_tcp_option_nop {
69+
b.extract<Tcp_option_nop_h>(vec.next.nop);
70+
transition start;
71+
}
72+
state parse_tcp_option_ss {
73+
b.extract<Tcp_option_ss_h>(vec.next.ss);
74+
transition start;
75+
}
76+
state parse_tcp_option_s {
77+
b.extract<Tcp_option_s_h>(vec.next.s);
78+
transition start;
79+
}
80+
state parse_tcp_option_sack {
81+
tmp_4 = b.lookahead<bit<24>>();
82+
b.extract<Tcp_option_sack_h>(vec.next.sack, (bit<32>)((tmp_4[15:8] << 3) + 8w240));
83+
transition start;
84+
}
85+
state noMatch {
86+
verify(false, error.NoMatch);
87+
transition reject;
88+
}
89+
}
90+
91+
parser pr<H>(packet_in b, out H h);
92+
package top<H>(pr<H> p);
93+
top<Tcp_option_h[10]>(Tcp_option_parser()) main;
94+

0 commit comments

Comments
 (0)